WPF: Bind Collection с коллекцией в ListBox с группами - PullRequest
8 голосов
/ 22 мая 2009

иногда WPF слишком сложен для меня. У меня есть "Window1" с коллекцией "Групп". «Группа» - это класс с коллекцией «Персона». В конце это должен быть список контактов. Я просто хочу показать группы с их личностью в ListBox, где имя группы в списке групп равно свойству Name моего класса «Groups».

Я пытался с CollectionViewSource, привязанным к "Collection". Группы отображаются правильно, но элементы списка совпадают с именами групп. Таким образом, у каждой группы есть только один элемент: название группы.

Многие примеры здесь показывают группирование предметов только с одной коллекцией. Что я могу сделать, это установить имя группы как свойство «Персона». Но тогда я не могу сосчитать (и это действительно необходимо): - сколько человек в каждой группе - сколько из этих лиц имеет статус «Онлайн».

Я использую linq в классе "Group", чтобы посчитать это. Спасибо за любой совет, помогающий мне начать.

Ответы [ 2 ]

21 голосов
/ 22 мая 2009

Ну, я не уверен, что вы этого хотите добиться, но вот способ, которым вы можете попробовать:

Предполагая, что ваши классы такие:

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>
8 голосов
/ 22 мая 2009

Если у вас есть копия Программирование 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, который показывает настраиваемые атрибуты, такие как 'some PropertyValue (Count)' - привязать один TextBlock к {Binding SomeProperty}, а другой к {Binding ItemCount}

НТН

...