1

我有一个 WPF 应用程序,它有一个 ViewBox 来显示我的集合中的项目,为我的结果显示一个 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 添加到此 Binding 以使其工作。

和一个类似的 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 回答