#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
.