1

コレクション内の項目を表示するための ViewBox を持つ WPF アプリがあり、結果を 2 列のグリッドで表示します。

私がやりたいことは、コレクション内のアイテムの数に応じて、列の数を変更することです。たとえば、リスト内のアイテムが 10 個未満の場合、それらを 1 列だけに表示します。リストに 10 個のアイテムがある場合、それらを 2 列で表示します。リストに 20 個の項目がある場合、3 列を表示します。

これが私が現在持っているものです:

<Viewbox>
   <ItemsControl ItemsSource="{Binding myCollection}" Style="{DynamicResource myStyle}" />
</Viewbox>

myStyle が現在定義しているものは次のとおりです。

<Style x:Key="myStyle" TargetType="{x:Type ItemsControl}">
   <Setter Property=ItemsControl.ItemsPanel">
      <Setter.Value>
         <ItemsPanelTemplate>
           <UniformGrid Columns="2" />
         </ItemsPanelTemplate>
      </Setter.Value>
   </Setter>
</Style>

このコードを上記の要件に合わせて機能させるにはどうすればよいですか? ありがとう。

4

2 に答える 2

2

Columns次のように、プロパティをアイテムの数にバインドし、適切なものを使用しIValueConverterて列の数を決定できます。

<UniformGrid Columns="{Binding Items.Count, Converter={local:ItemsToColumnConverter}}" />

動作させるには、このバインディングにRelativeSourceを追加する必要がある場合があることに注意してください。

そしてそれに似たIValueConverter:

public class ItemsToColumnConverter : IValueConverter
{
    // ...
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int numItems = (int)value;
        if (numItems < 10)
            return 1;
        else if (numItems < 20)
            return 2;
        else if (numItems < 30)
            return 3;
        else
            return numItems / 10;
    }

    public object ConvertBack(...)
    {
        throw new NotSupportedException();
    }
}

もちろん、そのコンバーターに、if-elseif-elseのものをすべて回避する別の数学ロジックを使用させることもできます。

于 2010-05-03T13:34:57.520 に答える
1

DataTrigger を使用して特定のスタイルを設定するのはどうですか? 「if size then columns」タプルの数が少ない場合は、実行可能かもしれません。
ItemsPanelStyleSelector に相当するものはありません (ItemContainerStyleSelector に似ています)。

更新:動作します。他の回答も見てみたいと思いますが。ValueConverter を使用して、Columns の値を ValueConverter.Convert(list.Count) によって返される値にバインドします。よりクリーンなサウンドになります。

   public string[] Options { get; set;}

   public bool NeedsTwoColumns
   {
       get
       {
           return this.Options.Length > 4;
       }
   }

//Xaml
<ListBox ItemsSource="{Binding Options}">
            <ListBox.Style>
                <Style>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding NeedsTwoColumns}" Value="True">
                            <Setter Property="ItemsControl.ItemsPanel">
                                <Setter.Value>
                                    <ItemsPanelTemplate>
                                        <UniformGrid Columns="2"/>
                                    </ItemsPanelTemplate>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListBox.Style>
        </ListBox>
    <ListBox ItemsSource="{Binding Options}">
        <ListBox.Resources>
            <local:MyConverter x:Key="ListLengthToColumnCountConverter"/>
        </ListBox.Resources>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Columns="{Binding Options.Length, Converter={StaticResource ListLengthToColumnCountConverter}}"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>

//ValueConverter
public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int listSize = (int)value;
        return (int)(listSize / 3);
    } ...
于 2010-05-03T11:02:57.403 に答える