WPF-привязка данных в виде дерева в MVVM

#c# #wpf #xaml #mvvm #treeview

#c# #wpf #xaml #mvvm #просмотр дерева

Вопрос:

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

У меня есть модель, в которой я определяю свой собственный класс:

 public class ItemOfWorld : INotifyPropertyChanged
{
    #region Fields
    private ObservableCollection<ItemOfWorld> _Items;
    private string _Name;
    private ItemOfWorld _Parent;
    #endregion

    #region FieldDeclaration
    public ObservableCollection<ItemOfWorld> Items 
    { 
        get
        {
            return _Items;
        }
        set
        {
            _Items = value;
            OnPropertyChanged("Items");
        }
    }

    public string Name
    {
        get
        {
            return _Name;
        }
        set 
        {
            _Name = value;
            OnPropertyChanged("Name");
        }
    }

    public ItemOfWorld Parent
    {
        get
        {
            return _Parent;
        }
        set
        {
            _Parent = value;
            OnPropertyChanged("Parent");
        }
    }

    #endregion

    public ItemOfWorld(ItemOfWorld parent)
    {
        Items = new ObservableCollection<ItemOfWorld>();
        Parent = parent;
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion
}

public class MyWorld:ItemOfWorld
{
    public MyWorld():base(null)
    {
        Name = "MyWorld";
        Items.Add(new Ions(this));
    }
}

public class Ions : ItemOfWorld
{
    public Ions(ItemOfWorld parent)
        : base(parent)
    {
        Name = "Ions";
        Parent = parent;
    }
}

public class Molecules : ItemOfWorld
{
    public Molecules(ItemOfWorld parent)
        : base(parent)
    {
        Name = "Molecules";
        Parent = parent;
    }
}
 

У меня есть ViewModel, где я создаю класс MyWorld:

 internal class ItemsOfWorldViewModel
{
    #region Fields
    private ItemOfWorld _MyItem;
    #endregion

    #region FieldDeclaration
    public ItemOfWorld MyItem
    {
        get
        {
            return _MyItem;
        }
        set
        {
            _MyItem = value;
        }
    }
    #endregion



    public ItemsOfWorldViewModel()
    {
        MyItem = new MyWorld();
    }

}
 

И, наконец, у меня есть представление с помощью TreeView toolbox с простым кодом:

  ItemsOfWorldViewModel myworld=new ItemsOfWorldViewModel();
 TreeView1.DataContext = myworld;
 

Мой вопрос: как я могу показать в своем TreeView свою иерархию без использования локальных источников?

 -MyWorld
     -->Ions
     -->Molecules
 

Если я реализую простой текстовый блок, он работает без каких-либо дополнительных библиотек и локальных источников, просто простой DataContext в коде и в XAML:

 <TextBox x:Name="TextBlock2" Text="{Binding MyItem.Name}"></TextBox>
 

Комментарии:

1. Возможно, эту статью стоит прочитать.

2. Спасибо, я уже прочитал это) И в своем примере он использует local-source.. Я просто не могу понять, почему в случае TextBlock я не определил какую-либо дополнительную переменную — достаточно DataContext, но в случае TreeView я должен добавить пространство имен в XAML для свойства типа данных TreeView..

Ответ №1:

Используйте HierarchicalDataTemplate в качестве TreeView.ItemTemplate

     <TreeView ItemsSource="{Binding MyItem.Items}">
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type local:ItemOfWorld }" ItemsSource = "{Binding Path=Items}">
                    <TextBlock Text="{Binding Path=Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
 

Комментарии:

1. Возможно ли не использовать локальную переменную? В вашем ответе я должен определить ‘xmlns: local’, но я уже привязал данные в DataContext. Насколько я понимаю, это не очень хороший способ реализовать модель MVVM с локальной переменной, может быть, я ошибаюсь..

2. Насколько я понимаю, это не очень хороший способ реализовать модель MVVM с локальной переменной, может быть, я ошибаюсь … вы ошибаетесь. Определение префикса пространства имен XAML не имеет абсолютно никакого отношения к MVVM.