WPF中CompositeCollection的使用

    有没有可能遇到这样子的需求,在ListBox里希望列表内加入不同种类的数据,显示的时候又能根据这些数据的类型使用不同的显示方式(在WPF中用DataTemplate来实现,这个大家可能耳熟能详了)。

    答案显然是肯定的,有这种需求存在。微软童鞋在WPF框架内考虑到大家的这种交互需求了。解决方案就是使用CompositeCollection。

    咋用呢? 举个栗子吧。

    在c#源文件中创建ChineseGod类和ChinesesGods类,如下所示:

    public class ChineseGod
    {
        public string Name { get; set; }
        public ChineseGod(string n)
        {
            Name = n;
        }
    }
    public  class ChineseGods : ObservableCollection<ChineseGod>
    {
        public ChineseGods()
        {
            Add(new ChineseGod("盘古"));
            Add(new ChineseGod("伏羲"));
            Add(new ChineseGod("女娲"));
        }
    }

    c#源代码就如上所示,很简单。接下来是XMAL文件:

    <Window.Resources>
        <c:ChineseGods x:Key="ChineseGodsData"/>

        <XmlDataProvider x:Key="FriendsData" XPath="Friends/Person">
            <x:XData>
                <Friends xmlns="">
                    <Person Name="Jason" Parent="c"/>
                    <Person Name="Hercules" Parent="d"/>
                    <Person Name="Bellerophon" Parent="e"/>
                    <Person Name="Theseus" Parent="f"/>
                    <Person Name="Odysseus" Parent="g"/>
                    <Person Name="Perseus" Parent="h"/>
                </Friends>
            </x:XData>
        </XmlDataProvider>

        <DataTemplate DataType="{x:Type c:ChineseGod}">
            <TextBlock Text="{Binding Path=Name}" Foreground="Gold"/>
        </DataTemplate>
        <DataTemplate DataType="Person">
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBlock Text="{Binding XPath=@Name}" Foreground="Cyan" Width="60"/>
                <Button Content="{Binding XPath=@Parent}" Width="100"></Button>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>

    <StackPanel>
        <TextBlock FontSize="18" FontWeight="Bold" Margin="10" HorizontalAlignment="Center">Composite Collections Sample</TextBlock>
        <ListBox Name="myListBox" Height="300" Width="200" Background="White">
            <ListBox.ItemsSource>
                <CompositeCollection>
                    <CollectionContainer Collection="{Binding Source={StaticResource ChineseGodsData}}" />
                    <CollectionContainer Collection="{Binding Source={StaticResource FriendsData}}" />
                    <ListBoxItem Foreground="Red">Other Listbox Item 1</ListBoxItem>
                    <ListBoxItem Foreground="Red">Other Listbox Item 2</ListBoxItem>
                </CompositeCollection>
            </ListBox.ItemsSource>
        </ListBox>
    </StackPanel>

    如上图所示,我们在ListBox.ItemsSource里头不是直接给ItemsSource赋一个集合,而是通过CompositeCollection将不同类型的集合组合在一起,就像CompositeCollection这个单词名称一样,它是一个组合,将不通的东西都组装在一起了。像这个例子,组合了三种:

    第一种

<CollectionContainer Collection="{Binding Source={StaticResource ChineseGodsData}}" />

    这种方式,将ListBox绑定到了ChineseGods集合。它的显示方式由下面这个模板定义:

        <DataTemplate DataType="{x:Type c:ChineseGod}">
            <TextBlock Text="{Binding Path=Name}" Foreground="Gold"/>
        </DataTemplate>

    第二种

<CollectionContainer Collection="{Binding Source={StaticResource FriendsData}}" />

    这种方式,将ListBox绑定到了Friends集合,这个集合是用XmlDataProvider方式提供。未来有时间再讲XmlDataProvider这个东东。它的显示方式有下面的这个模板定义:

        <DataTemplate DataType="Person">
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBlock Text="{Binding XPath=@Name}" Foreground="Cyan" Width="60"/>
                <Button Content="{Binding XPath=@Parent}" Width="100"></Button>
            </StackPanel>
        </DataTemplate>

    第三种

扫描二维码关注公众号,回复: 569024 查看本文章
<ListBoxItem Foreground="Red">Other Listbox Item 2</ListBoxItem>

    至此,大家估计可以想象的出整个显示的结果。嗯,就是如下所示:


    这个图就很有说服力了,确实ListBox可以包容万象,可以包含不同种类的数据!

    本例子期初来源于微软,本人对这个例子做了一些改动,由于微软原先的例子显示的全是string字符串,组合起来感觉不出类型的差异,结果还是不太容易让人理解CompositeCollection的含义。

猜你喜欢

转载自blog.csdn.net/qq_16587307/article/details/79602993