Динамическая группировка / вложение плоских данных в TreeView - PullRequest
2 голосов
/ 22 сентября 2011

Я хотел бы взять плоский список объектов и представить их в TreeView, используя пользовательские группы.

public enum DocumentType { Current, Inactive, Transition, Checkpack, TechLog, Delivery }
public enum Status { Approved, Rejected, Pending }

public class Document
{
    public string Name { get; set; }
    public DateTime Created { get; set; }
    public string CreatedBy { get; set; }
    public DateTime Modified { get; set; }
    public string ModifiedBy { get; set; }
    public DocumentType Type { get; set; }
    public Status Status { get; set; }
}

Например ... Пользователь может захотеть увидеть этот список с группой верхнего уровня «Статус» и вторым уровнем «Имя». Все это должно быть настраиваемо с помощью пользовательского интерфейса, и я изо всех сил пытаюсь найти лучший способ добиться этого.

Я кратко рассмотрел объект CollectionViewSource, но не смог найти хороший способ заставить его динамически создавать TreeView.

У меня такое чувство, что мне нужно сделать несколько умных шаблонов в XAML - это насколько я могу ...

<Window.Resources>
    <DataTemplate x:Key="DocumentTemplate">
        <DockPanel>
            <TextBlock Text="{Binding Name}" />
        </DockPanel>
    </DataTemplate>

    <HierarchicalDataTemplate x:Key="GroupTemplate"
                              ItemsSource="{Binding Path=Items}"
                              ItemTemplate="{StaticResource DocumentTemplate}">
        <TextBlock Text="{Binding Path=Name}" />
    </HierarchicalDataTemplate>
</Window.Resources>
<Grid>
    <TreeView ItemsSource="{Binding Documents.View.Groups}"
              ItemTemplate="{StaticResource GroupTemplate}"/>
</Grid>


    public CollectionViewSource Documents
    {
        get
        {
            var docs = new CollectionViewSource();
            docs.Source = DocumentFactory.Documents;
            docs.GroupDescriptions.Add(new PropertyGroupDescription("CreatedBy"));
            return docs;
        }
    }

Конечно, здесь отображается только группа верхнего уровня ("CreatedBy").


Прочитав вопрос ниже, мне удалось придумать лучший вопрос ...

Мой вопрос: возможно ли иметь общий HierarchicalDataTemplate для TreeView, который отображает пользовательские группы, примененные к CollectionViewSource.

1 Ответ

0 голосов
/ 22 сентября 2011

Честно говоря, это должно быть помечено как ошибка в WPF.Я тоже попробовал и обнаружил, что Documents.View.Groups выдает ошибку привязки для свойства View, имеющего нулевое значение.

Также

 <TextBlock Text="{Binding Path=Name}" />

правильно в GroupTemplate, но не в DocumentTemplate,Обратите внимание, что Groups имеют специальный тип GroupItem, где Name - это одно из таких свойств, которое содержит значение, по которому произошла группировка.

С другой стороны, в DocumentTemplate мы должны ссылаться на свойство, которое нам нужно отобразить на элементах конечных узлов, например, в моем примере я использовал Employee.FirstName (я сгруппировал по Gender).

 <DataTemplate x:Key="DocumentTemplate">
      <DockPanel>
          <TextBlock Text="{Binding FirstName}" />
      </DockPanel>
 </DataTemplate>

Теперь, чтобы привязка вступила в силу, мне пришлось представить конвертер, который просто возвращает Groups.

public class GroupsConverter : IValueConverter
{
    public object Convert(object value, ...)
    {
        return ((CollectionViewSource)value).View.Groups;
    }

    ....
}

И привязка в виде дерева была изменена таким образом ...

<TreeView x:Name="treeView"                  
          ItemsSource="{Binding Path=Documents,
                                Converter={StaticResource GroupsConverter}}"
          ItemTemplate="{StaticResource GroupTemplate}" />

Тогда это сработало для меня.

Это тебе помогает?

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