【问题标题】:WPF: Bind Collection with Collection to a ListBox with groupsWPF:将集合与集合绑定到具有组的列表框
【发布时间】:2009-05-22 06:31:10
【问题描述】:

有时 WPF 对我来说太复杂了。我的“Window1”拥有一组“Group”。 “Group”是一个包含“Person”集合的类。最后,这应该是一个联系人列表。我只想在 ListBox 中显示组及其人员,其中列表组的组名称等于我的类“组”的名称属性。

我已尝试将 CollectionViewSource 绑定到“集合”。组显示正确,但列表中的项目与组名称相同。所以每个组只有一项:它的组名。

这里的许多示例显示了只有一个集合的项目分组。我可以做的是将组名设置为“Person”的属性。但后来我数不清(这确实是必要的): - 每组有多少人 - 其中有多少人拥有“状态”“在线”。

我在“组”类中使用 linq 来计算它。 感谢您提供任何帮助我开始的建议。

【问题讨论】:

    标签: c# wpf listbox grouping collections


    【解决方案1】:

    好吧,我不确定这是否是您想要实现的目标,但您可以尝试以下方法:

    假设你的课程是这样的:

    public class Group
    {
        public string Name { get; set; }
        public List<Contact> Contacts { get; set; }
    }
    
    public class Contact
    {
        public string Name { get; set; }
        public bool IsOnline { get; set; }
    }
    

    您可以将 ListBox.ItemTemplate 设置为另一个 ListBox 绑定到 Contacts 属性,例如:

    <CollectionViewSource x:Key="groups" Source="{Binding}" >
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="Name" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
    
    <DataTemplate x:Key="groupTemplate" DataType="Group">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Name}" />
        </StackPanel>
    </DataTemplate>
    
    <ListBox ItemsSource="{Binding Source={StaticResource groups}}">
        <ListBox.GroupStyle>
            <GroupStyle HeaderTemplate="{StaticResource groupTemplate}" />
        </ListBox.GroupStyle>
        <ListBox.ItemTemplate>
            <DataTemplate DataType="Contact">
                <ListBox ItemsSource="{Binding Contacts}">
                    <ListBox.ItemTemplate>
                        <DataTemplate DataType="Contact">
                            <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    

    您必须稍微设置内部列表框的样式。

    编辑:使用TreeView的另一种解决方案

    <DataTemplate DataType="Contact">
       <TextBlock Text="{Binding Name}" />
    </DataTemplate>
    
    <TreeView ItemsSource="{Binding Source={StaticResource groups}}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate DataType="Group" ItemsSource="{Binding Contacts}">
                <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
    

    【讨论】:

    • 这非常有用,与我的旧解决方案相同,在旧解决方案中,我每个组都有一个扩展器和一个联系人列表框。这里的问题是,你可以为每个列表选择一个人,但我想你可以用一个人来做。我尝试复制 Windows Live Messenger 2009 联系人列表的 UI。我认为他们只使用了一个 ListBox 和一个 Expander 作为该组的 ControlTemplate。但我也假设,他们将组定义为财产。但我真的不知道,他们如何计算在线人数。顺便说一句,你的课程是正确的。
    • 为什么不用TreeView控件来显示分层数据?
    • 你完全正确!我想,这肯定会解决我的问题。对于“为什么”,我没有答案。我没有经常使用 TreeView 控件。但这对我的问题来说是最好的。谢谢!
    • TreeView 正是我所需要的。
    【解决方案2】:

    如果您有Programming WPF 的副本,请跳至第 221 页。如果没有,我会总结一下(以我无能的方式)

    首先,您不需要手动对 Person 对象进行分组。

    如果每个 Person 对象都有一个 Group 属性,

    People people = // retrieve the List<Person> somehow
    ICollectionView view = CollectionViewSource.GetDefaultView(people);
    view.GroupDescriptions.Add( new PropertyGroupDescription("Group") );
    

    从 ItemsControl 派生的所有控件都可以显示分组项,所以

    // the XAML
    <ListBox ... ItemsSource={Binding}>
      <ListBox.GroupStyle>
        <x:Static Member="GroupStyle.Default" />
      </ListBox.GroupStyle>
    </ListBox>
    

    您还可以定义一个自定义 GroupStyle 并指定 GroupStyle.HeaderTemplate 来定义一个新的 DataTemplate,该 DataTemplate 显示自定义属性,如“一些 PropertyValue (Count)” - 将一个 TextBlock 绑定到{Binding SomeProperty},将另一个绑定到{Binding ItemCount}

    HTH

    【讨论】:

    • 谢谢,首先。我的 Person 对象还没有 group 属性。我想避免它。我不明白如何处理计数(只有逻辑,TextBlock 的事实很清楚)。这是一些代码,如果它可以帮助你。 enum OnlineStatus { ONLINE, OFFLINE } class Person { // 每个组的标题应该计算 // OnlineStatus "Online" 存在多少人。公共在线状态状态{获取;放; } } 类组 { public List Persons = new List(); } class Window1 { public List Groups = new List; }
    • +1, {Binding ItemCount} 是我需要的答案!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 2012-08-23
    • 1970-01-01
    相关资源
    最近更新 更多