Catel: Treeview HierarchicalDataTemplate - PullRequest
       28

Catel: Treeview HierarchicalDataTemplate

0 голосов
/ 16 октября 2018

Я начал создавать небольшое тестовое приложение для MVVM с Catel.Я попытался показать TreeView и создать одну ViewModel для отображения всех элементов.Но я получаю сообщение об ошибке.

<TreeView ItemsSource="{Binding ChildCollection}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding ChildCollection}">
            <local:TreeViewItem DataContext="{Binding}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>nter code here

TreeViewItem - это всего лишь TextBlock.Но поскольку это userControl, Catel должен создать для него ViewModel.Следующий код ViewModel упрощен.

public class TreeViewItemVm : ViewModelBase
{
    public TreeViewItemVm(ModelBase model)
    {
        Model = model;

        if(model is Group)
            // Set Properties
        else if(model is Customer)
            // Set Properties
        else if(model is Product)
            // Set Properties
    }

    [Model]
    public ModelBase Model {get; set; }
    public string DisplayText {get; set; }
    public ObservableCollection<ModelBase> ChildCollection {get; set; }
    public Command OpenItemCommand { get; private set; }

При запуске я получаю ошибку

System.Windows.Data Ошибка: 40: Ошибка пути BindingExpression: 'ChildCollection'свойство не найдено в' объекте '' 'Клиент' ...

Таким образом, HierarchicalDataTemplate ItemsSource="{Binding ChildCollection}" ищет модель вместо ViewModel.

Модель не должна реализовывать Команду.Таким образом, ответ здесь не является конкретным.Есть ли способ достичь этого?Или я должен определить это явно для типа echt с его собственным CustomControl, как это сделано в этом базовом примере .Или кто-нибудь знает конкретный пример Catel?

1 Ответ

0 голосов
/ 16 октября 2018
<TreeView ItemsSource="{Binding RootTreeViewItemVms}">
    <TreeView.Resources>
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate DataType={x:Type TreeViewItemVm} 
                                      ItemsSource="{Binding ChildCollection}">
                <TextBlock Text={Binding DisplayText} />
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    <TreeView.Resources>
</TreeView>

У вас также должны быть определенные типы ViewModel, которые наследуются от базового TreeViewItemVm.

public abstract class TreeViewItemVm: ViewModelBase
{
    public TreeViewItemVm()
    {
        ChildCollection = new ObservableCollection<TreeViewItemVm>();
    }

    public ObservableCollection<TreeViewItemVm> ChildCollection {get; }
    public Command OpenItemCommand { get; private set; }
    public string DisplayText {get; set; }
}

public abstract class TreeViewItemVm<T> where T: ModelBase
{
    public TreeViewItemVm(T model)
    {
        Model = model;
    }

    public T Model {get;}
}

public class GroupTreeViewItemVm: TreeViewItem<Group>
{
    public GroupTreeViewItemVm(Group group): base(group)
    {
        // group specific stuff here
    }
}

etc....

При необходимости вы можете создавать различные HierarchicalDataTemplates для каждого конкретного типа ViewModel.

edit

В вашем классе TreeViewItemVm также есть недостаток.

public ObservableCollection<ModelBase> ChildCollection {get; set; }

должно быть

public ObservableCollection<TreeViewItemVm> ChildCollection {get; set; }
...