0

これは私の関連記事からのいくつかのコンテキストです: How to databind using to a 2d array of objects of different types

だから私は持っています:

List<List<FarmyardSpace>>

これをグリッドのセルのボタンとして表現したい。グリッド内のセルのサイズを定義する必要があるため、関連記事のように UniformGrid を使用できません。理想的には、データに行フィールドと列フィールドを定義する必要はありません (ただし、おそらくこれは 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 ではなくリストであるため、バインドする Column プロパティがないためだと思います。また、内側の ItemsControl の RowDefinitions と ColumnDefinitions の両方で試しました。これは例外を取り除きますが、特に列が外側のItemsControlで宣言されている関連投稿でUniformGridを使用するときに機能するソリューションを考えると、機能せず、私には間違っているようです。

とにかく、これを理解するための助けをいただければ幸いです。事前に感謝します!

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 に答える