我正在尝试布局网格,以便它可以拥有动态数量的列,并且每个数据绑定控件都会自动添加到正确的列中(基于数据上下文中的索引)。
考虑保龄球,虽然通常总是10,但我不想在XAML中定义10列并单独添加每个帧。我正在尝试以编程方式进行。
这是我的XAML:
<ItemsControl x:Name="BowlingPlayers" ItemsSource="{Binding Game.Players}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"/>
<ScrollViewer HorizontalScrollBarVisibility="Visible" Grid.Column="1">
<ItemsControl ItemsSource="{Binding Frames}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid Loaded="BowlingGrid_OnLoaded">
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Height="64" BorderBrush="White" BorderThickness="1" Loaded="BowlingFrame_OnLoaded">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Ball1}"/>
<Border Grid.Column="1" BorderBrush="White" BorderThickness="1,0,0,1">
<TextBlock Text="{Binding Ball2}"/>
</Border>
<TextBlock Grid.ColumnSpan="2" Grid.Row="1" Text="{Binding Score}"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
然后在代码隐藏中:
private void BowlingGrid_OnLoaded(object sender, RoutedEventArgs e) {
var grid = (Grid)sender;
if (grid.ColumnDefinitions.Any()) return;
var player = grid.DataContext as BowlingPlayer;
if (player != null) {
// Add columns for each frame
foreach (var frame in player.Frames) {
grid.ColumnDefinitions.Add(new ColumnDefinition() {Width = new GridLength(1, GridUnitType.Star)});
}
}
}
private void BowlingFrame_OnLoaded(object sender, RoutedEventArgs e) {
var border = (Border) sender;
var frame = border.DataContext as BowlingFrame;
var presenter = VisualTreeHelper.GetParent(border);
var grid = VisualTreeHelper.GetParent(presenter) as Grid;
if (grid != null) {
var player = grid.DataContext as BowlingPlayer;
if (player != null) {
var frameIndex = player.Frames.IndexOf(frame);
Grid.SetColumn(border, frameIndex + 1);
}
}
}
它“有点”工作,似乎所有帧都被放入第一列,而不是它们各自的列索引。
在没有XAML中的硬编码宽度的情况下,还有另一种方法可以解决这个问题吗?如果我使用水平StackPanel并给每个帧(边框)一个明确的宽度和高度,它可以工作,但我希望它缩放到可用的宽度。
基本上,CSS3 flexbox等效布局。
答案 0 :(得分:0)
我在这里找到了WPF UniformGrid
的等效演示:
http://www.jeff.wilcox.name/2009/01/uniform-grid/
切换到那之后,它确实按预期工作!现在不需要使用任何自定义代码。