2010-06-14 45 views
2

我有一个奇怪的布局的ItemsControl。不规则的布局ItemsControl

我有以下模式的4x6的网格:

1 2 3 4 
13 14 15 16 
5 6 7 8 
17 18 19 20 
9 10 11 12 
21 22 23 24 

是否有一个简单的方法来做到这一点?我是否应该使用6个项目控件并采用列表中的“部分”?有没有一个很好的方法来做到这一点?通知怎么样?

重要的是要注意,我可能会,也可能不是很重要的,拥有全部24项存在,但布局需要维护(认为它像宾果卡上的东西充满槽)

编辑:

理想情况下,我希望能够列出清单中的项目,并在清单中的项目上做一些有趣的排序/填充类型的内容。例如,如果我有一个ObservableCollection几个单位,单位有一个属性“索引”,我想有一个视图消费品集合生成,自动使用索引来填充列表。我猜一个可观察的字典可以工作,但看起来很糟糕。也许一个新的自定义布局面板是为了?

回答

2

在纯XAML中为您的ItemsControl使用自定义模板有一个巧妙的方法。这是最简单的,如果所有的“牌”有一个固定的大小,100×100说:

<!-- Wrap each card in a decorator twice as high as the card cell --> 
<DataTemplate x:Key="ItemInDoubleHighBox"> 
    <Decorator Width="100" Height="200"> 
    <Decorator Width="100" Height="100" ClipToBounds="True"> 
     <ContentPresenter /> 
    </Decorator> 
    </Decorator> 
</DataTemplate> 

<!-- Define a template for use with WrapPanel --> 
<ItemsPanelTemplate x:Key="WrapPanelTemplate"> 
    <WrapPanel /> 
</ItemsPanelTemplate> 

<!-- Now the actual ItemsControl template --> 
<ControlTemplate TargetType="ItemsControl"> 
    <Grid Width="600" Height="600" ClipToBounds="True"> 

    <!-- Items 1 to 12 --> 
    <ItemsControl ItemsSource="{TemplateBinding ItemsSource}" 
        ItemsPanel="{StaticResource WrapPanelTemplate}" 
        ItemTemplate="{StaticResource ItemInDoubleHighBox}" /> 

    <!-- Items 13 to 24 --> 
    <ItemsControl ItemsSource="{TemplateBinding ItemsSource}" 
        ItemsPanel="{StaticResource WrapPanelTemplate}" 
        ItemTemplate="{StaticResource ItemInDoubleHighBox}" 
        RenderTransform="1 0 0 1 0 -500" /> 

    </Grid> 
</ControlTemplate> 

它是如何工作的:DataTemplate中导致的项目是“双倍行距”,只有1-12可见,和对的RenderTransform第二个ItemsControl使项目13-24,也是“双间隔”出现在第一行项目之间的空间。

注意:您可以使高度和宽度可以进行数据绑定,但需要更多XAML。只需添加ScaleTransforms,即可在XAML中出现“200”,“500”或“600”。例如,要处理“200”,您可以在ScaleY =“0.5”的内部装饰器上设置比例变换,并在ScaleY =“2”的每个ItemsControl上设置比例变换。现在外部装饰器的高度将为100,这可以是数据绑定的。其他常量可以通过类似的内容前后缩放来处理。而且由于WPF在渲染之前合并了所有变换,所以额外的变换基本上不会花费任何费用。

+0

为什么使用装饰器?我也很困惑,这是如何“拆分”我的项目到1-12和13-24 否则,我喜欢这个答案。 – Firoso 2010-06-15 16:30:13

0

WPF使这个相当微不足道。基本上你只需要指定一个ItemsPanelTemplate。

<ListBox> 
    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <UniformGrid Columns="4" /> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
</ListBox> 

现在,添加到列表框的任何项目将根据面板,其在这种情况下是一个UniformGrid的布局逻辑地布置。

请注意,您仍然需要按照您希望它们出现的顺序保留收藏中的物品。所以在将它们添加到列表框之前,我会先排序它们。如果你需要在集合中创建“洞”,那么我会使用某种类型的占位符对象(也许new object()会做),而不是试图使用复杂的布局逻辑来传播项目。

+0

没有专门针对WPF的收集适配器类吗? – Firoso 2010-06-14 23:05:51

+0

我不确定你的意思。这个问题真的有两个部分。布局方面(使ListBox中的项目显示在网格中)很简单。但是我并不完全理解你打算如何将这些物品放入收藏中。 – Josh 2010-06-14 23:09:52

+0

为您发布编辑。 – Firoso 2010-06-15 00:45:16