1

这个问题是这个问题的后续。我从这个站点获得了一些建议,并决定开始学习MVVM实现,以使用 TreeViews。话虽如此,我对 MVVM 还是很陌生,而且我仍然熟悉语法和实现。

我有一个显示整数类型数据的 TreeView,但我希望它改为使用字符串。树还允许用户通过选择 TreeViewItem,然后在文本框中输入新的整数标题,然后单击按钮来添加到任何级别。

示例图像

我希望父母、孩子和孙子在启动时可以使用预定义的名称。需要注意的另一件事是,该用户只能在子级级别添加到 TreeView(因此他们只能添加孙子级)。

模型

public class TreeViewModel : PropertyChangedBase
{
    public string Value { get; set; }

    public ObservableCollection<TreeViewModel> Items { get; set; }

    public CollectionView ItemsView { get; set; }

    public TreeViewModel(string value)
    {
        Items = new ObservableCollection<TreeViewModel>();
        ItemsView = new ListCollectionView(Items)
        {
            SortDescriptions =
            {
                new SortDescription("Value",ListSortDirection.Ascending)
            }
        };
        Value = value;
    }
}

视图模型

public class SortedTreeViewWindowViewModel : PropertyChangedBase
{
    private string _newValueString;

    public string NewValueString
    {
        get { return _newValueString; }
        set
        {
            _newValueString = value;

            OnPropertyChanged("NewValueString");
        }
    }

    public TreeViewModel SelectedItem { get; set; }

    public ObservableCollection<TreeViewModel> Items { get; set; }

    public ICollectionView ItemsView { get; set; }

    public SortedTreeViewWindowViewModel()
    {
        Items = new ObservableCollection<TreeViewModel>();
        ItemsView = new ListCollectionView(Items) { SortDescriptions = { new SortDescription("Value", ListSortDirection.Ascending) } };
    }

    public void AddNewItem()
    {
        ObservableCollection<TreeViewModel> targetcollection;

        //Insert the New Node as a Root node if nothing is selected.
        targetcollection = SelectedItem == null ? Items : SelectedItem.Items;

        if (_newValueString != null)
        {
            targetcollection.Add(new TreeViewModel(_newValueString));
            NewValueString = string.Empty;
        }
    }
}

查看代码隐藏

public partial class Window1 : Window
{
    public SortedTreeViewWindowViewModel ViewModel { get { return DataContext as SortedTreeViewWindowViewModel; } set { DataContext = value; } }

    public Window1()
    {
        InitializeComponent();
        ViewModel = new SortedTreeViewWindowViewModel()
            {
                Items = {new TreeViewModel("Test")}
            };
    }

    private void AddNewItem(object sender, RoutedEventArgs e)
    {
        ViewModel.AddNewItem();
    }

    private void OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        ViewModel.SelectedItem = e.NewValue as TreeViewModel;
    }
}

非常感谢帮忙。我希望通过这些可以帮助我了解如何编辑和构建 ViewModel,以便我将来可以学习更多即兴创作。

更新

TreeView 现在由字符串组成,因此该部分已解决。不过,我仍然需要默认节点的帮助。我已更新我的代码以反映此更改。

4

1 回答 1

3

以下是我的建议

  • 将您拥有 int 的位置更改为字符串。TreeView 应该处理该更改。
  • 在 ViewModel 的构造函数中,手动插入默认节点。确保您了解如何使用 TreeView,因为这会影响您的 Model 和 ViewModel 的设计并自然地改进实现。

这是一个非常简单的示例,如何在 ViewModel 中填充树,该树绑定到 View 中的 TreeView:

看法

<Window x:Class="TreeViewExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <StackPanel>
            <TreeView ItemsSource="{Binding Tree}"/>
        </StackPanel>
    </StackPanel>
</Window>

查看代码隐藏

namespace TreeViewExample
{
    using System.Windows;

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            DataContext = new MainWindowViewModel();
            InitializeComponent();
        }
    }
}

视图模型

namespace TreeViewExample
{
    using System.Collections.ObjectModel;
    using System.Windows.Controls;

    class MainWindowViewModel
    {
        public ObservableCollection<TreeViewItem> Tree { get; set; }

        public MainWindowViewModel()
        {
            Tree = new ObservableCollection<TreeViewItem>();
            Tree.Add(GetLoadedTreeRoot());
        }

        private TreeViewItem GetLoadedTreeRoot()
        {
            TreeViewItem parent = new TreeViewItem() { Header = "Parent" };
            TreeViewItem child1 = new TreeViewItem() { Header = "Child 1" };
            TreeViewItem child2 = new TreeViewItem() { Header = "Child 2" };
            TreeViewItem grandchild1 = new TreeViewItem() { Header = "Grandchild 1" };
            TreeViewItem grandchild2 = new TreeViewItem() { Header = "Grandchild 2" };

            child1.Items.Add(grandchild1);
            child2.Items.Add(grandchild2);
            parent.Items.Add(child1);
            parent.Items.Add(child2);
            return parent;
        }
    }
}

产生:

  • 家长
    • 孩子 1
      • 孙子 1
    • 孩子 2
      • 孙子 2

额外的想法:

  • 要清理您的代码隐藏,您可能会查找一个命令实现,其中有很多。尽管您有时需要它,但请尽可能避免在代码隐藏中使用代码。我真的很喜欢这个示例,因为它向您展示了一个通用的 MVVM 实现,而无需深入了解与命令相关的高级主题(ItemTemplates、Interactivity 命名空间等)。
于 2013-07-31T15:50:59.003 回答