Группировка дерева с другим источником - PullRequest
3 голосов
/ 28 марта 2011

Я новичок в мире WPF и пытаюсь реализовать приложение в соответствии с шаблоном проектирования MVVM. У меня возникли некоторые проблемы с использованием древовидных представлений.

Моя модель - это список сообщений журнала (из разных приложений) со следующими свойствами: сообщение, серьезность, приложение. У меня есть одна коллекция с 6 предметами, которые принадлежат двум разным приложениям. Я хочу, чтобы мой вид дерева выглядел следующим образом:

Приложение A
Ошибка
Первое сообщение об ошибке (aaa)
Второе сообщение об ошибке (bbb)
Предупреждение
Первое предупреждение (ccc)
Приложение B
Предупреждение
Первое предупреждение (ддд)
Информация
Первое информационное сообщение (eee)
Второе информационное сообщение (fff)

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

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

Можно ли использовать только один список с разными группировками?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 29 марта 2011

Вы можете легко сгруппировать ваши данные с CollectionView, даже вложенным способом:

ObservableCollection<LogEntry> data = new ObservableCollection<LogEntry>(new LogEntry[]
{
    new LogEntry("App1", "Warning", "Msg1"),
    new LogEntry("App1", "Error", "Msg2"),
    new LogEntry("App1", "Warning", "Msg3"),
    new LogEntry("App2", "Error", "Msg4"),
    new LogEntry("App2", "Info", "Msg5"),
    new LogEntry("App2", "Info", "Msg6"),
});
ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(data);
view.GroupDescriptions.Add(new PropertyGroupDescription("Application"));
view.GroupDescriptions.Add(new PropertyGroupDescription("Severity"));
Data = view;

(Вы также можете создать представление CollectionView в XAML, это только пример)

Теперь вы можете отобразить это с помощью DataTemlates:

<TreeView ItemsSource="{Binding Data.Groups}">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type CollectionViewGroup}" ItemsSource="{Binding Items}">
            <TextBlock Text="{Binding Name}"/>
        </HierarchicalDataTemplate>
        <DataTemplate DataType="{x:Type local:LogEntry}">
            <TextBlock Text="{Binding Message}"/>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

Похоже на это:
http://i52.tinypic.com/xeeut5.png

1 голос
/ 29 марта 2011

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

Вы можете использовать несколько вложенных CollectionViewSource с вложенным TreeView, если вы не хотите изменятьбазовая коллекция ( адаптировано из этого поста ).Тем не менее, я не знаю, будет ли это соответствовать онлайн-обновлениям базовой коллекции, я решил, что это свойство Messages в контексте данных:

<!-- First level grouping on the application name -->
<CollectionViewSource x:Key="ApplicationGroups"
                      Source="{Binding Messages}">
    <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="Application" />
    </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

Затем вы настраиваете шаблон для приложения иУровни серьезности:

<HierarchicalDataTemplate x:Key="ApplicationTemplate">
    <!-- Nested tree view for the severity -->
    <TreeView>
        <TreeView.Resources>
            <!-- Since this TreeView will receive a Group as its DataContext
                 we will bind to its Items property, containing the objects
                 which are a member of its group
             -->
            <CollectionViewSource x:Key="SeverityGroups"
                                  Source="{Binding Items}">
                <CollectionViewSource.GroupDescriptions>
                    <PropertyGroupDescription PropertyName="Severity" />
                </CollectionViewSource.GroupDescriptions>
            </CollectionViewSource>

            <!-- Message Template -->
            <DataTemplate x:Key="MessageTemplate">
                <TextBlock Text="{Binding Message}" />
            </DataTemplate>

            <!-- Severity Hierarchy Template -->
            <HierarchicalDataTemplate x:Key="SeverityTemplate"
                                      ItemsSource="{Binding Items}"
                                      ItemsTemplate="{StaticResource MessageTemplate}">
                <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
        </TreeView.Resources>

        <!-- Application sub-Tree View -->
        <TreeViewItem Header="{Binding Name}"
                      ItemsSource="{Binding Groups, Source={StaticResource SeverityGroups}}"
                      ItemTemplate="{StaticResource SeverityTemplate}" />
    </TreeView>
</HierarchicalDataTemplate>

Затем ваш 1011 * установит для ItemsSource свойство Groups представления коллекции, например:

<TreeView ItemsSource="{Binding Groups, Source={StaticResource ApplicationGroups}}"
          ItemTemplate="{StaticResource ApplicationTemplate}" />

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...