代码之家  ›  专栏  ›  技术社区  ›  Brett Rigby

WPF:根据数据量更改视图框的样式

  •  1
  • Brett Rigby  · 技术社区  · 15 年前

    我有一个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>
    

    如何使此代码符合上述要求?谢谢。

    2 回复  |  直到 13 年前
        1
  •  2
  •   gehho    15 年前

    你可以把 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-else if其他东西。

        2
  •  1
  •   Gishu    15 年前

    使用DataTrigger设置特定样式如何?如果有少量的“if-size-then-columns”元组,可能是可行的。
    我看到没有与itemspanelstyleselector等效的itemspanelstyleselector(类似于itemcontainerstyleselector)。

    更新:它起作用了。尽管我也会看看其他的反应。使用ValueConverter将列值绑定到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);
        } ...
    
    推荐文章