Управляет случайным перемещением при изменении размера окна

#c# #wpf #wpf-controls #window-resize

#c# #wpf #wpf-элементы управления #окно-изменение размера

Вопрос:

Я создал приложение wpf. Код XAML для приложения приведен ниже. При запуске окно выглядит великолепно, однако, когда я пытаюсь изменить размер окна, элементы управления беспорядочно перемещаются. Я хочу, чтобы элементы управления оставались на месте, как в обычном приложении Windows. Также я новичок в WPF. Любые предложения будут оценены.

Я вставил изображение исходного и измененного окна.

 <Window x:Class="demoUI.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:demoUI"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="8*"/>
            <RowDefinition Height="17*"/>
            <RowDefinition Height="397*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="39*"/>
            <ColumnDefinition Width="113*"/>
            <ColumnDefinition Width="46*"/>
            <ColumnDefinition Width="12*"/>
            <ColumnDefinition Width="149*"/>
            <ColumnDefinition Width="38*"/>
            <ColumnDefinition Width="141*"/>
            <ColumnDefinition Width="256*"/>
        </Grid.ColumnDefinitions>
        <!--<Border BorderBrush="Black" BorderThickness="1" Grid.Column="6" Height="100" Margin="9.2,13,21.6,0" Grid.Row="1" Grid.RowSpan="2" VerticalAlignment="Top" HorizontalAlignment="Stretch"/>-->
        <Menu Margin="0,-4,56.2,5.8" Grid.ColumnSpan="2" Grid.RowSpan="2" >
            <MenuItem Header="File">
                <MenuItem Header="Open Log File"/>
                <MenuItem Header="Open Workspace"/>
                <Separator/>
                <MenuItem Header="Save as Workspace"/>
                <MenuItem Header="Set Path host file"/>
                <Border BorderBrush="Black" BorderThickness="1" Margin="-34,-117,-656.4,37.6"/>
            </MenuItem>
            <MenuItem Header="Control" Grid.Row="0" Grid.Column="1" Width="60">
                <MenuItem Header="Open Command Line View"/>
            </MenuItem>
        </Menu>
        <TextBlock Text="Connect To" Width="65" Height="Auto" HorizontalAlignment="Left" Margin="4,16.2,0,360.6" Grid.Row="2" Grid.ColumnSpan="2"/>
        <TextBox TextWrapping="Wrap" Text="IP/HostName" Margin="37.8,14.2,11.4,360.6" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Grid.ColumnSpan="2"/>
        <TextBox TextWrapping="Wrap" Text="Line" Margin="100.8,46.2,12.4,328.6" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Grid.ColumnSpan="2"/>

        <TextBlock Text="Protocol" Width="78" Height="Auto" HorizontalAlignment="Left" Margin="111.6,9,0,383.6" Grid.Column="4" Grid.ColumnSpan="3" Grid.RowSpan="2" Grid.Row="1"/>

        <StackPanel VerticalAlignment="Top" Grid.Column="3" Orientation="Horizontal" Grid.ColumnSpan="2" Height="48" Margin="2.6,0.2,0,0" Grid.Row="2" HorizontalAlignment="Left" Width="78">
            <Button Content="Play" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20" Margin="4.5,14.2,0,0" Width="32"/>
            <Button Content="Stop" HorizontalAlignment="Right" VerticalAlignment="Top" Height="20" Margin="4.5,14.2,0,0" Width="32"/>
        </StackPanel>

        <StackPanel Orientation="Vertical" 
                    VerticalAlignment="Top" Grid.Column="4" Grid.ColumnSpan="2" Grid.Row="2"
                    HorizontalAlignment="Center" Width="34" Margin="123.6,6.2,28.8,0" Height="115">
            <TextBlock Text="Rx" Width="20" Height="Auto" HorizontalAlignment="Center"/>
            <CheckBox Margin="5,5,4.6,5" Height="14" />
            <CheckBox Margin="5,5,4.6,5" Height="14" RenderTransformOrigin="0.492,-0.286" />
            <CheckBox Margin="5,5,4.6,5" Height="14" />
            <CheckBox Margin="5,5,4.6,5" Height="14" />
        </StackPanel>
        <StackPanel Orientation="Vertical" 
                    VerticalAlignment="Top" Grid.Column="5" Grid.ColumnSpan="2" Grid.Row="2"
                    HorizontalAlignment="Left" Margin="4.8,6.2,0,0" Height="124" Width="36">
            <TextBlock Text="Tx" Width="20" Height="Auto" HorizontalAlignment="Center" />
            <CheckBox Margin="5,5,4.8,5" Height="14" />
            <CheckBox Margin="5,5,4.8,5" Height="14" />
            <CheckBox Margin="5,5,4.8,5" Height="14" />
            <CheckBox Margin="5,5,4.8,5" Height="14" />
        </StackPanel>


        <TextBlock Text="Log Cmd" Width="65" Height="Auto" HorizontalAlignment="Left" Margin="9,51.2,0,325.6" Grid.Row="2" Grid.ColumnSpan="2"/>
        <TextBlock TextWrapping="Wrap" Text="RSP" Margin="93.6,25.2,15.2,348.6"  Grid.Column="4" Grid.Row="2" />
        <TextBlock TextWrapping="Wrap" Text="RTU" Margin="93.6,49.2,15.2,327.6" Grid.Column="4" Grid.Row="2" />
        <TextBlock TextWrapping="Wrap" Text="Error" Margin="93.6,69.2,15.2,307.6" Grid.Column="4" Grid.Row="2"/>
        <TextBlock TextWrapping="Wrap" Text="Info" Margin="93.6,96.2,15.2,280.6" Grid.Column="4" Grid.Row="2" />

        <ComboBox x:Name="Job"
                  VerticalAlignment="Bottom" Margin="38.8,0,16,324.6"
                  Height="23" Grid.Row="2" Grid.Column="1">
            <ComboBoxItem Content="Trace"/>
            <ComboBoxItem Content="List"/>
            <ComboBoxItem Content="Dump"/>
            <ComboBoxItem Content="Off"/>
        </ComboBox>
        <StackPanel Grid.Column="3" Grid.Row="2" Grid.ColumnSpan="2" Margin="3.6,52.2,82.2,315.6">
            <Button Content="Send" VerticalAlignment="Top" Height="20" Margin="3,0,0,0" HorizontalAlignment="Left" Width="69"/>
        </StackPanel>
    </Grid>
</Window>
  

введите описание изображения здесь
введите описание изображения здесь

Комментарии:

1. Я бы посоветовал попробовать найти руководство по WPF и layout в XAML — узнайте, что делают VerticalAlignment и HorizontalAlignment — попробуйте установить для них значения «Top» и «Left» соответственно для начала в ваших текстовых блоках. Сопоставьте поля для элементов, которые должны быть выровнены.

2. @PaulF большое спасибо. При установке VerticalAlignment =»Top» и HorizontalAlignment = «Left» мои элементы управления не растягиваются. Однако они все еще прокручиваются. Есть идеи о том, как заставить их стоять в фиксированном положении?

3. Что вы подразумеваете под «прокруткой»? Если вы имеете в виду, что они исчезают, когда окно становится слишком маленьким, тогда вы могли бы установить минимальную высоту / ширину окна.. Вы также можете рассмотреть возможность использования фиксированных высот, а не относительных высот в ваших определениях строк сетки (удалить *)

4. Еще одна вещь, которую стоит попробовать, это присвоить каждому элементу фиксированную высоту, а не устанавливать значение Auto. Установите третье и четвертое значения полей равными 0 для всех элементов. Убедитесь, что все элементы имеют VerticalAlignment =»Top». Это может устранить большинство проблем с перемещением элементов или их исчезновением при изменении размера по вертикали. Затем вам нужно будет поиграть с выравниваниями, шириной, удалением относительного размера столбцов и т.д. Для изменения размера по горизонтали. Лучший способ изучить это самостоятельно — в сочетании с книгами / руководствами по макету WPF / XAML.

Ответ №1:

Прямой причиной блуждания TextBoxes и ComboBox является то, что для их VerticalAlignment установлено значение Center , и они смещены обратно к началу строки с использованием гигантских нижних маркеров.

Они также находятся в пределах третьей строки a Grid , и значение всех строк Height задано таким образом, чтобы они масштабировались до размера родительского контейнера (окна). Звездочка ‘*’ в Height="8*" , Height="17*" и т.д. Приводит к тому, что строки заполняют оставшееся пространство в их родительском элементе, стремясь к заданным пропорциям.

Основным виновником всего этого, скорее всего, является использование дизайнера для перетаскивания всего на свои места, а не осознанное использование различных панелей / контейнеров, которые доступны в WPF.

По крайней мере, вы должны создать начальную настройку панели, написав код самостоятельно. Это приведет к гораздо более чистому и удобному в обслуживании коду. Я рекомендую использовать конструктор только в качестве инструмента обратной связи в начале вашего пути с WPF.

Вероятно, это тот макет, который вы ищете:

 <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Menu Grid.Row="0">
        <MenuItem Header="File">
            <MenuItem Header="Open Log File" />
            <MenuItem Header="Open Workspace" />
            <Separator />
            <MenuItem Header="Save as Workspace" />
            <MenuItem Header="Set Path host file" />
        </MenuItem>
        <MenuItem Header="Control">
            <MenuItem Header="Open Command Line View" />
        </MenuItem>
    </Menu>
    <WrapPanel Grid.Row="1" Margin="10">
        <WrapPanel.Resources>
            <Style TargetType="Grid">
                <Setter Property="Margin" Value="0,0,20,0" />
            </Style>
        </WrapPanel.Resources>
        <Grid>
            <Grid.Resources>
                <Style TargetType="TextBox">
                    <Setter Property="Margin" Value="3" />
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                </Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Margin" Value="3" />
                    <Setter Property="VerticalAlignment" Value="Center" />
                </Style>
                <Style TargetType="ComboBox">
                    <Setter Property="Margin" Value="3" />
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock VerticalAlignment="Center" Text="Connect To" />
            <TextBox
                Grid.Column="1"
                Grid.ColumnSpan="2"
                Text="IP/HostName" />
            <TextBlock Grid.Row="1" Text="Log Cmd" />
            <ComboBox
                x:Name="Job"
                Grid.Row="1"
                Grid.Column="1">
                <ComboBoxItem Content="Trace" />
                <ComboBoxItem Content="List" />
                <ComboBoxItem Content="Dump" />
                <ComboBoxItem Content="Off" />
            </ComboBox>
            <TextBox
                Grid.Row="1"
                Grid.Column="2"
                VerticalContentAlignment="Center"
                Text="Line" />
        </Grid>
        <Grid>
            <Grid.Resources>
                <Style TargetType="Button">
                    <Setter Property="Margin" Value="3" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Button Content="  Play  " />
            <Button Grid.Column="1" Content="  Stop  " />
            <Button
                Grid.Row="1"
                Grid.ColumnSpan="2"
                Content="  Job  " />
        </Grid>
        <Grid>
            <Grid.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="Margin" Value="3" />
                </Style>
                <Style TargetType="CheckBox">
                    <Setter Property="Margin" Value="3" />
                </Style>
            </Grid.Resources>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.ColumnSpan="3" Text="Protocol" />
            <TextBlock
                Grid.Row="1"
                Grid.Column="1"
                Text="Rx" />
            <TextBlock
                Grid.Row="1"
                Grid.Column="2"
                Text="Tx" />
            <TextBlock Grid.Row="2" Text="RSP" />
            <CheckBox Grid.Row="2" Grid.Column="1" />
            <CheckBox Grid.Row="2" Grid.Column="2" />

        </Grid>
    </WrapPanel>
</Grid>
  

Кроме того, я бы рекомендовал прочитать следующую статью о панелях и контейнерах в WPF https://www.codeproject.com/Articles/140613/WPF-Tutorial-Layout-Panels-Containers-Layout-Trans

Редактировать: Кроме этого, я советую избегать жесткой настройки Width и Height для контейнеров и большинства элементов управления. Также не бойтесь вставлять контейнеры друг в друга для достижения желаемого результата. Создавать вложенные контейнеры и работать с ними намного проще, чем с mega Grid .

Ответ №2:

Основная проблема заключается в ваших определениях строк / столбцов. Используя отмеченные звездочками значения, вы даете приложению указание масштабировать ширину / высоту относительно других столбцов / строк.

Другими словами, чтобы элементы управления оставались на своих местах при изменении размера, удалите звездочки из ColumnDefinitions / RowDefinitions .