WPF:根据数据量更改ViewBox的样式

时间:2010-05-03 10:37:58

标签: wpf binding styles viewbox

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

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

2 个答案:

答案 0 :(得分:2)

您可以将Columns属性绑定到项目数,并使用适当的IValueConverter来确定列数,如下所示:

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

请注意,您可能需要向此Binding添加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的东西。

答案 1 :(得分: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);
    } ...