0

这是我的相关帖子中的一些上下文: How to databind using to a 2d array of objects of different types

所以我有一个:

List<List<FarmyardSpace>>

我希望将其表示为网格单元格中的按钮。我不能像在相关帖子中那样使用 UniformGrid,因为我需要定义网格中单元格的大小。理想情况下,我不想在我的数据中定义 Row 和 Column 字段(尽管也许这应该由 ViewModel 以某种方式处理?前几天刚开始学习这些东西,但我仍然在 WPF 和 MVVM 上纠结) .

这是我最新的尝试,它不起作用(实际上引发了异常),在这个特定的示例中,我依赖于 FarmyardSpaces 上存在的 Column 和 Row 属性:

<ItemsControl ItemsSource="{Binding FarmyardGrid}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding}">
                <ItemsPanelTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="15"/>
                            <RowDefinition />
                            <RowDefinition Height="15"/>
                            <RowDefinition />
                            <RowDefinition Height="15"/>
                            <RowDefinition />
                            <RowDefinition Height="15"/>
                        </Grid.RowDefinitions>
                    </Grid>
                </ItemsPanelTemplate>
                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="ContentPresenter">
                        <Setter Property="Grid.Row" Value="{Binding Row}"/>
                    </Style>
                </ItemsControl.ItemContainerStyle>
            </ItemsControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="15"/>
                    <ColumnDefinition />
                    <ColumnDefinition Width="15"/>
                    <ColumnDefinition />
                    <ColumnDefinition Width="15"/>
                    <ColumnDefinition />
                    <ColumnDefinition Width="15"/>
                    <ColumnDefinition />
                    <ColumnDefinition Width="15"/>
                    <ColumnDefinition />
                    <ColumnDefinition Width="15"/>
                </Grid.ColumnDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Grid.Column" Value="{Binding Column}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

我认为这不起作用的部分原因是外部 ItemsControl 包含的项目不是 FarmyardSpaces 而是 List,因此它们没有要绑定的 Column 属性。我还尝试使用内部 ItemsControl 中的 RowDefinitions 和 ColumnDefinitions。这消除了异常,但也不起作用,对我来说似乎是错误的,特别是考虑到在相关帖子中使用 UniformGrid 时有效的解决方案,其中列在外部 ItemsControl 中声明。

无论如何,我将不胜感激任何帮助解决这个问题,在此先感谢!

4

1 回答 1

1

如果您的集合项上有属性,可以指定它们在网格中的位置,那显然是最简单的,这就是您现在设置的。如果没有,您可以使用转换器为您计算出每个项目的索引,然后将其分配为行/列值 - 它在两个维度上的工作方式相同。这是基本的转换器:

public class ItemToIndexConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        object item = values.FirstOrDefault();
        IList collection = values.OfType<IList>().LastOrDefault();

        if (collection == null || item == null)
            return 0;

        return collection.IndexOf(item);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

和您的 XAML 的修改版本(减少到 3x3)从父 ItemsControl 获取当前项目和完整集合以传递到转换器:

<ItemsControl ItemsSource="{Binding FarmyardGrid}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="15"/>
                                <RowDefinition />
                                <RowDefinition Height="15"/>
                            </Grid.RowDefinitions>
                        </Grid>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="ContentPresenter">
                        <Setter Property="Grid.Row">
                            <Setter.Value>
                                <MultiBinding>
                                    <MultiBinding.Converter>
                                        <local:ItemToIndexConverter/>
                                    </MultiBinding.Converter>
                                    <Binding/>
                                    <Binding Path="ItemsSource"
                                             RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}"/>
                                </MultiBinding>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ItemsControl.ItemContainerStyle>
            </ItemsControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="15"/>
                    <ColumnDefinition />
                    <ColumnDefinition Width="15"/>
                </Grid.ColumnDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Grid.Column">
                <Setter.Value>
                    <MultiBinding>
                        <MultiBinding.Converter>
                            <local:ItemToIndexConverter/>
                        </MultiBinding.Converter>
                        <Binding/>
                        <Binding Path="ItemsSource"
                                 RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}"/>
                    </MultiBinding>
                </Setter.Value>
            </Setter>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>
于 2013-02-01T05:24:59.570 回答