WPF UserControl 组件网格定义问题
WPF UserControl component grid definition issue
我有两列的简单用户控件,在第一列我有 DataGrid
:
<UserControl x:Class="Caliburn_SimpleInjector_Sample.ViewModel.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
MinWidth="1100" MinHeight="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".20*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width=".70*" />
</Grid.ColumnDefinitions>
<DataGrid Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=Tasks, Mode=OneWay}"
SelectedItem="{Binding SelectedTask}"
AutoGenerateColumns="False" IsReadOnly="True"
CanUserResizeRows="False" GridLinesVisibility="None"
SelectionUnit="FullRow"
RowHeaderWidth="0"
FontSize="14">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Col 1" Binding="{Binding Find}" />
<DataGridTextColumn Header="Col 2" Binding="{Binding Action}" />
<DataGridTextColumn Header="Col 3" Binding="{Binding Status}" />
</DataGrid.Columns>
</DataGrid>
<GridSplitter Grid.Row="0" Grid.Column="1"
VerticalAlignment="Stretch"
ResizeBehavior="PreviousAndNext"
Width="5" Background="#FFBCBCBC" />
<StackPanel Grid.Row="0" Grid.Column="2" Background="Red"></StackPanel>
</Grid>
</UserControl>
让我们来看看我们有什么:
完美!这正是我需要的。
但是!如果我只是尝试为 DataGrid
内的每一列设置动态 Width
,整个模板就会损坏:
<DataGrid.Columns>
<DataGridTextColumn Width="0.2*" Header="Col 1 20%" Binding="{Binding Find}" />
<DataGridTextColumn Width="0.2*" Header="Col 2 20%" Binding="{Binding Action}" />
<DataGridTextColumn Width="0.6*" Header="Col 3 60%" Binding="{Binding Status}" />
</DataGrid.Columns>
结果如下:
还有一件有趣的事。如果您尝试开始调整 window 的大小 - 那么一切都会变得正常,例如:
ScreenCast
有人可以帮我解决这个问题吗?
提前致谢。
您尝试过将 MinWidth 和 Width 与 * 组合使用吗?请参见下面的示例:
<DataGrid.Columns>
<DataGridTextColumn MinWidth="0.2" Width="*" Header="Col 1 20%" Binding="{Binding Find}" />
<DataGridTextColumn MinWidth="0.2" Width="*" Header="Col 2 20%" Binding="{Binding Action}" />
<DataGridTextColumn MinWidth="0.6" Width="*" Header="Col 3 60%" Binding="{Binding Status}" /></DataGrid.Columns>
只需设置控件window宽高
<UserControl x:Class="Caliburn_SimpleInjector_Sample.ViewModel.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
MinWidth="1100" MinHeight="400"
Width="1100" Height="400"
>
控件将完美运行
问题在于空的StackPanel。您正在使用 * 表示动态 DataGridTextColumn 宽度。
- (star) 占用任何可用的剩余 space
详细讨论如下:
Meaning of * (asterisk) in a WPF ColumnDefinition? (weighted proportion of available space)
只需用控件填充 StackPanel,或者为了获得灵感,将 StackPanel 替换为 DataGrid 定义的副本。作为示例演示将是这样的:
<UserControl x:Class="Caliburn_SimpleInjector_Sample.ViewModel.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
MinWidth="1100" MinHeight="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".20*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width=".70*" />
</Grid.ColumnDefinitions>
<DataGrid Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=Tasks, Mode=OneWay}"
SelectedItem="{Binding SelectedTask}"
AutoGenerateColumns="False" IsReadOnly="True"
CanUserResizeRows="False" GridLinesVisibility="None"
SelectionUnit="FullRow"
RowHeaderWidth="0"
FontSize="14">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTextColumn Width="0.2*" Header="Col 1 20%" Binding="{Binding Find}" />
<DataGridTextColumn Width="0.2*" Header="Col 2 20%" Binding="{Binding Action}" />
<DataGridTextColumn Width="0.6*" Header="Col 3 60%" Binding="{Binding Status}" />
</DataGrid.Columns>
</DataGrid>
<GridSplitter Grid.Row="0" Grid.Column="1"
VerticalAlignment="Stretch"
ResizeBehavior="PreviousAndNext"
Width="5" Background="#FFBCBCBC" />
<DataGrid Grid.Row="0" Grid.Column="2" ItemsSource="{Binding Path=Tasks, Mode=OneWay}"
SelectedItem="{Binding SelectedTask}"
AutoGenerateColumns="False" IsReadOnly="True"
CanUserResizeRows="False" GridLinesVisibility="None"
SelectionUnit="FullRow"
RowHeaderWidth="0"
FontSize="14">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTextColumn Width="0.2*" Header="Col 1 20%" Binding="{Binding Find}" />
<DataGridTextColumn Width="0.2*" Header="Col 2 20%" Binding="{Binding Action}" />
<DataGridTextColumn Width="0.6*" Header="Col 3 60%" Binding="{Binding Status}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
然后您可以观察到控件的行为是正确的,因为没有 space 剩下的数据可供第一个数据网格列使用。
问题与 Caliburn
无关。与此处描述的问题完全相同:Window SizeToContent issue when child UserControl has grid with Column of max Width.
我按照此处建议的方式解决了我的问题:fix。
我有两列的简单用户控件,在第一列我有 DataGrid
:
<UserControl x:Class="Caliburn_SimpleInjector_Sample.ViewModel.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
MinWidth="1100" MinHeight="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".20*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width=".70*" />
</Grid.ColumnDefinitions>
<DataGrid Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=Tasks, Mode=OneWay}"
SelectedItem="{Binding SelectedTask}"
AutoGenerateColumns="False" IsReadOnly="True"
CanUserResizeRows="False" GridLinesVisibility="None"
SelectionUnit="FullRow"
RowHeaderWidth="0"
FontSize="14">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Col 1" Binding="{Binding Find}" />
<DataGridTextColumn Header="Col 2" Binding="{Binding Action}" />
<DataGridTextColumn Header="Col 3" Binding="{Binding Status}" />
</DataGrid.Columns>
</DataGrid>
<GridSplitter Grid.Row="0" Grid.Column="1"
VerticalAlignment="Stretch"
ResizeBehavior="PreviousAndNext"
Width="5" Background="#FFBCBCBC" />
<StackPanel Grid.Row="0" Grid.Column="2" Background="Red"></StackPanel>
</Grid>
</UserControl>
让我们来看看我们有什么:
完美!这正是我需要的。
但是!如果我只是尝试为 DataGrid
内的每一列设置动态 Width
,整个模板就会损坏:
<DataGrid.Columns>
<DataGridTextColumn Width="0.2*" Header="Col 1 20%" Binding="{Binding Find}" />
<DataGridTextColumn Width="0.2*" Header="Col 2 20%" Binding="{Binding Action}" />
<DataGridTextColumn Width="0.6*" Header="Col 3 60%" Binding="{Binding Status}" />
</DataGrid.Columns>
结果如下:
还有一件有趣的事。如果您尝试开始调整 window 的大小 - 那么一切都会变得正常,例如: ScreenCast
有人可以帮我解决这个问题吗?
提前致谢。
您尝试过将 MinWidth 和 Width 与 * 组合使用吗?请参见下面的示例:
<DataGrid.Columns>
<DataGridTextColumn MinWidth="0.2" Width="*" Header="Col 1 20%" Binding="{Binding Find}" />
<DataGridTextColumn MinWidth="0.2" Width="*" Header="Col 2 20%" Binding="{Binding Action}" />
<DataGridTextColumn MinWidth="0.6" Width="*" Header="Col 3 60%" Binding="{Binding Status}" /></DataGrid.Columns>
只需设置控件window宽高
<UserControl x:Class="Caliburn_SimpleInjector_Sample.ViewModel.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
MinWidth="1100" MinHeight="400"
Width="1100" Height="400"
>
控件将完美运行
问题在于空的StackPanel。您正在使用 * 表示动态 DataGridTextColumn 宽度。
- (star) 占用任何可用的剩余 space
详细讨论如下: Meaning of * (asterisk) in a WPF ColumnDefinition? (weighted proportion of available space)
只需用控件填充 StackPanel,或者为了获得灵感,将 StackPanel 替换为 DataGrid 定义的副本。作为示例演示将是这样的:
<UserControl x:Class="Caliburn_SimpleInjector_Sample.ViewModel.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
MinWidth="1100" MinHeight="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".20*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width=".70*" />
</Grid.ColumnDefinitions>
<DataGrid Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=Tasks, Mode=OneWay}"
SelectedItem="{Binding SelectedTask}"
AutoGenerateColumns="False" IsReadOnly="True"
CanUserResizeRows="False" GridLinesVisibility="None"
SelectionUnit="FullRow"
RowHeaderWidth="0"
FontSize="14">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTextColumn Width="0.2*" Header="Col 1 20%" Binding="{Binding Find}" />
<DataGridTextColumn Width="0.2*" Header="Col 2 20%" Binding="{Binding Action}" />
<DataGridTextColumn Width="0.6*" Header="Col 3 60%" Binding="{Binding Status}" />
</DataGrid.Columns>
</DataGrid>
<GridSplitter Grid.Row="0" Grid.Column="1"
VerticalAlignment="Stretch"
ResizeBehavior="PreviousAndNext"
Width="5" Background="#FFBCBCBC" />
<DataGrid Grid.Row="0" Grid.Column="2" ItemsSource="{Binding Path=Tasks, Mode=OneWay}"
SelectedItem="{Binding SelectedTask}"
AutoGenerateColumns="False" IsReadOnly="True"
CanUserResizeRows="False" GridLinesVisibility="None"
SelectionUnit="FullRow"
RowHeaderWidth="0"
FontSize="14">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTextColumn Width="0.2*" Header="Col 1 20%" Binding="{Binding Find}" />
<DataGridTextColumn Width="0.2*" Header="Col 2 20%" Binding="{Binding Action}" />
<DataGridTextColumn Width="0.6*" Header="Col 3 60%" Binding="{Binding Status}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
然后您可以观察到控件的行为是正确的,因为没有 space 剩下的数据可供第一个数据网格列使用。
问题与 Caliburn
无关。与此处描述的问题完全相同:Window SizeToContent issue when child UserControl has grid with Column of max Width.
我按照此处建议的方式解决了我的问题:fix。