Windows 存储应用程序 ItemsControl HTML-table 类似行为

Windows store app ItemsControl HTML-table-like behavior

我正在尝试制作一个控件来显示自定义的复选框列表,如图所示:

我当前的实现使用 ItemsControl,它具有 VariableSizedWrapGrid 作为 ItemsPanelTemplate。但它使所有项目的大小相同...我无法弄清楚如何像 HTML table.

中那样按内容调整单元格大小

不幸的是,默认情况下没有这样的面板。

如果您的项目数量是静态的(或者至少列数是静态的),您可以使用 Grid 作为 ItemsPanelTemplate,并在 [= 中设置 Grid.RowGrid.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);
}