Windows 存储应用程序 ItemsControl HTML-table 类似行为
Windows store app ItemsControl HTML-table-like behavior
我正在尝试制作一个控件来显示自定义的复选框列表,如图所示:
我当前的实现使用 ItemsControl,它具有 VariableSizedWrapGrid 作为 ItemsPanelTemplate。但它使所有项目的大小相同...我无法弄清楚如何像 HTML table.
中那样按内容调整单元格大小
不幸的是,默认情况下没有这样的面板。
如果您的项目数量是静态的(或者至少列数是静态的),您可以使用 Grid
作为 ItemsPanelTemplate,并在 [= 中设置 Grid.Row
和 Grid.Column
14=]槽式转换器。
否则,您需要通过覆盖 ArrangeChildren 和 MeasureOverride 方法来实现您的自定义面板。我有我的自定义面板可以解决这个问题。如果你找不到更好的,我可以分享给你
编辑: 我假设您不希望所有单元格的大小相同。在这种情况下,您可以使用 UniformGrid。
我附上了使用 Grid + 一些代码隐藏的示例代码。代码隐藏不违反 MVVM 关注点分离,因为代码隐藏中有纯视图逻辑。
<ItemsControl ItemsSource="{Binding ItemsSource}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid Initialized="ItemsPanel_Initialized" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="FrameworkElement">
<EventSetter Event="Loaded" Handler="Item_Loaded" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
private void ItemsPanel_Initialized(object sender, EventArgs e)
{
//generate row and column definitions
for (int i = 0; i < ViewModel.ColumnsCount; i++)
{
((Grid)sender).ColumnDefinitions.Add(new ColumnDefinition{ Width = new GridLength()});
}
for (int i = 0; i <= ViewModel.ItemsSource.Count / ViewModel.ColumnsCount; i++)
{
((Grid)sender).RowDefinitions.Add(new RowDefinition{ Height = new GridLength() });
}
}
private void Item_Loaded(object sender, RoutedEventArgs e)
{
var itemContainer = (FrameworkElement) sender;
var itemsControl = ItemsControl.ItemsControlFromItemContainer(itemContainer);
var itemIndex = itemsControl.ItemContainerGenerator.IndexFromContainer(itemContainer);
Grid.SetColumn(itemContainer, itemIndex % ViewModel.ColumnsCount);
Grid.SetRow(itemContainer, itemIndex / ViewModel.ColumnsCount);
}
我正在尝试制作一个控件来显示自定义的复选框列表,如图所示:
我当前的实现使用 ItemsControl,它具有 VariableSizedWrapGrid 作为 ItemsPanelTemplate。但它使所有项目的大小相同...我无法弄清楚如何像 HTML table.
中那样按内容调整单元格大小不幸的是,默认情况下没有这样的面板。
如果您的项目数量是静态的(或者至少列数是静态的),您可以使用 Grid
作为 ItemsPanelTemplate,并在 [= 中设置 Grid.Row
和 Grid.Column
14=]槽式转换器。
否则,您需要通过覆盖 ArrangeChildren 和 MeasureOverride 方法来实现您的自定义面板。我有我的自定义面板可以解决这个问题。如果你找不到更好的,我可以分享给你
编辑: 我假设您不希望所有单元格的大小相同。在这种情况下,您可以使用 UniformGrid。
我附上了使用 Grid + 一些代码隐藏的示例代码。代码隐藏不违反 MVVM 关注点分离,因为代码隐藏中有纯视图逻辑。
<ItemsControl ItemsSource="{Binding ItemsSource}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid Initialized="ItemsPanel_Initialized" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="FrameworkElement">
<EventSetter Event="Loaded" Handler="Item_Loaded" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
private void ItemsPanel_Initialized(object sender, EventArgs e)
{
//generate row and column definitions
for (int i = 0; i < ViewModel.ColumnsCount; i++)
{
((Grid)sender).ColumnDefinitions.Add(new ColumnDefinition{ Width = new GridLength()});
}
for (int i = 0; i <= ViewModel.ItemsSource.Count / ViewModel.ColumnsCount; i++)
{
((Grid)sender).RowDefinitions.Add(new RowDefinition{ Height = new GridLength() });
}
}
private void Item_Loaded(object sender, RoutedEventArgs e)
{
var itemContainer = (FrameworkElement) sender;
var itemsControl = ItemsControl.ItemsControlFromItemContainer(itemContainer);
var itemIndex = itemsControl.ItemContainerGenerator.IndexFromContainer(itemContainer);
Grid.SetColumn(itemContainer, itemIndex % ViewModel.ColumnsCount);
Grid.SetRow(itemContainer, itemIndex / ViewModel.ColumnsCount);
}