Группировка со строго типом группового ключа в WPF

Каждый найденный мной пример и статья о группировании элементов по одному свойству и их отображении. Но то, что у меня есть, это строго групповой ключ, который я хочу отобразить. Вот модели и логика группировки:

Интерфейс элемента

public interface IItem {
    string Title { get; }
    string ToolTip { get; }
    object Icon { get; }
    Type GroupType { get; }
}

IItem имеет много реализаций, подобных этому:

public class Item : IItem {
    public string Title { get; private set; }
    public string ToolTip { get; private set; }
    public object Icon { get; private set; }

    // I have many implementation of IGroup which I will use them in GroupType properties.
    public Type GroupType { get { return SomeGroupTypeHere; } }
}

А вот и интерфейс группы:

public interface IGroup {
    string Name { get; }
    object Icon { get; }
}

и у этого есть много реализаций также.

Я собираю их в моей модели зрения (получая помощь от Autofac):

public class MyViewModel {

    private readonly IEnumerable<IGrouping<IGroup, IItem>> _items;

    public MyViewModel(IEnumerable<IGroup> groups, IEnumerable<IItem> items){
        _items = items.GroupBy(t => {
            var g = groups.First(u => u.GetType() == t.GroupType);
            return g;
        });
    }

    public IEnumerable<IGrouping<IGroup, IItem>> Items {
        get { return _items; }
    }
}

Теперь проблема в том, как отобразить эти сгруппированные элементы в ItemsControl?

<ItemsControl ItemsSource="{Binding Items}" Margin="20 20 20 0">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate >
            <!-- here is my template that uses IItem properties, example: -->
            <Button Content="{Binding Title}"
                    ToolTip="{Binding ToolTip}"/>
        </DataTemplate >
    </ItemsControl.ItemTemplate>
</ItemsControl>

Код только отображает только первый элемент в каждой группе, и я понятия не имею, что делать, чтобы показать заголовки группы (которые используют IGroup свойства), а также показать все элементы в каждой группе. Любое предложение, пожалуйста? Любая статья или блог-пост будет очень полезен. Заранее спасибо.

1 ответ

Вы хотите использовать HierarchicalDataTemplate когда вы хотите отобразить сгруппированные данные, измените ItemsControl.ItemTemplate в `HierarchialDataTemplate'.

Пример (и непроверенный) HierarchialDataTemplate:

<ItemsControl ItemsSource="{Binding Items}" Margin="20 20 20 0">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding}">
            <Button Content="{Binding Title}" ToolTip="{Binding ToolTip}"/>
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate >
                    <Button Content="{Binding Title}" ToolTip="{Binding ToolTip}"/>
                </DataTemplate >
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Обратитесь к этому посту за пошаговым подходом к HierarchialDataTemplates.

ОБНОВИТЬ

Я пробовал вышеупомянутый HierarchialDataTemplate с вашим кодом, и он, похоже, не работает. Однако, если я заменю ItemsControl с TreeView, он работает как ожидалось.

Итак, я думаю, вы могли бы хотеть ItemControl для вашего случая протестированный пример кода, как показано ниже:

<ItemsControl ItemsSource="{Binding Items}" Margin="20 20 20 0">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal" IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Button Content="{Binding Title}" ToolTip="{Binding ToolTip}"/>
                <ItemsControl ItemsSource="{Binding}" Margin="15,0,0,0">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate >
                            <Button Content="{Binding Title}" ToolTip="{Binding ToolTip}"/>
                        </DataTemplate >
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Вот снимок экрана с этим вложенным ItemsControls.

ОБНОВЛЕНИЕ 2 Я думаю, что вам нужно обновить шаблон для отображения группы, текущий шаблон не делает этого.

Обновленный шаблон ниже:

<ItemsControl ItemsSource="{Binding Items}" Margin="20 20 20 0">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal" IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Button Content="{Binding Key.Name}" />
                <ItemsControl ItemsSource="{Binding}" Margin="15,0,0,0">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate >
                            <Button Content="{Binding Title}" ToolTip="{Binding ToolTip}"/>
                        </DataTemplate >
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

И полученный скриншот:

Другие вопросы по тегам