2013-02-01 111 views
0

下面是我的一个相关的帖子一些背景: How to databind using to a 2d array of objects of different types绑定列表<列表<MyClass>>细胞在网格

所以我有一个:

List<List<FarmyardSpace>> 

我希望这可以表示为按钮在网格的单元格中。我不能像在相关文章中那样使用UniformGrid,因为我需要定义Grid中单元格的大小。理想情况下,我不想在我的数据中定义Row和Column字段(尽管也许这应该由ViewModel以某种方式处理?有一天刚开始学习这些东西,而且我仍然围绕着WPF和MVVM) 。

这里是我的最新尝试,这是不行的(事实上抛出异常),并在这个特殊的例子中,我依靠现有的FarmyardSpaces列和行属性:

<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包含的Items不是FarmyardSpaces而是List,所以它们没有要绑定的Column属性。我也尝试了内部ItemsControl中的RowDefinitions和ColumnDefinitions。这摆脱了异常,但也不起作用,似乎对我来说是错误的,尤其是考虑到在外部ItemsControl中声明Columns的相关帖子中使用UniformGrid时的解决方案。

无论如何,我会很感激任何帮助搞清楚这一点,在此先感谢!

回答

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的修改版本(削减到3×3)获得当前项目,并从父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> 
+0

好吧,我对于我现在没有得到这个,感觉不那么糟糕:)这个解决方案对我来说很有意义,但我认为将会有一种处理索引的不太复杂的方式,因为它似乎是想知道布局的一个非常基本的事情目的。感谢所有的帮助! – StuartMorgan