TreeView不显示存储在数据中的子节点

时间:2014-07-11 16:36:03

标签: c# wpf mvvm treeview

在我的程序中,我有TreeView数据备份(查看模型和数据模型)。添加到TreeView的每个项目都会添加一个子项目,但由于某种原因,孩子们在运行时没有反映。但是,我能够在调试期间看到孩子们和我的孩子们。 TreeView's数据模型中的属性包含NotifyPropertyChange其中的setter。

注意:早些时候我遇到了类似的问题,即新添加的节点(这些孩子的父母)也不会被显示出来。通过在树的xaml中设置DisplayMemberPath="DisplayName.Value"来纠正此问题。

TreeView's xaml:

TreeView ItemsSource="{Binding UserControl_DataModel.TreeViewViewModel.ObservableCollection<TreeViewDataModel>}" DisplayMemberPath="DisplayName.Value".../>

这是创建新节点并添加到TreeView(TreeViewViewModel)的地方:

private TreeViewDataModel createNewNode(StringItem nodeName)
{
    var newNode = new TreeViewDataModel ()
    {
        DisplayName = nodeName
    };

    newNode.Children.Add(new TreeViewDataModel () { DisplayName = nodeName});

    return newNode;
}

public void addNewLocNode(StringItem nodeName)
{
    TreeObservableCollection.Add(createNewNode(nodeName));
}

注意:StringItem是一个自定义类。在StringItem中,Value返回项的字符串值。 (例如:StringItem.Value

TreeViewDataModel中的Children属性:

public ObservableCollection<TreeViewDataModel> Children
{
    get { return _children ?? (_children = new ObservableCollection<TreeViewDataModel>()); }
    set
    {
        _children = value;
        NotifyPropertyChange(() => Children);
    }
}

为什么我的TreeView中没有显示子节点,我该如何解决?

1 个答案:

答案 0 :(得分:0)

您没有足够的代码让我知道您的具体设置。我试图让它与你已有的相似。我认为你应该能够解决这个问题。

截图:

enter image description here

XAML:

<Window x:Class="WpfApplication9.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:WpfApplication9"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TreeView ItemsSource="{Binding TreeObservableCollection}"> <!-- DisplayMemberPath="DisplayName.Value" - Can't set both DisplayMemberPath and ItemTemplate -->
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate DataType="{x:Type app:TreeViewDataModel}" ItemsSource="{Binding Children}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding DisplayName.Value}" />
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</Grid>

CODE:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication9
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<TreeViewDataModel> TreeObservableCollection { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            TreeObservableCollection = new ObservableCollection<TreeViewDataModel>();
            this.DataContext = this;
            this.Loaded += MainWindow_Loaded;
        }
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            addNewLocNode(new StringItem("A"));
            addNewLocNode(new StringItem("B"));
            addNewLocNode(new StringItem("C"));
            addNewLocNode(new StringItem("D"));
        }
        private TreeViewDataModel createNewNode(StringItem nodeName)
        {
            var newNode = new TreeViewDataModel()
            {
                DisplayName = nodeName
            };
            newNode.Children.Add(new TreeViewDataModel() { DisplayName = nodeName });
            return newNode;
        }

        public void addNewLocNode(StringItem nodeName)
        {
            TreeObservableCollection.Add(createNewNode(nodeName));
        }
    }
    public class StringItem
    {
        public string Value { get; set; }
        public StringItem(string val)
        {
            Value = val;
        }
    }
    public class TreeViewDataModel : System.ComponentModel.INotifyPropertyChanged
    {
        public StringItem DisplayName { get; set; }
        private ObservableCollection<TreeViewDataModel> _children;
        public ObservableCollection<TreeViewDataModel> Children
        {
            get { return _children ?? (_children = new ObservableCollection<TreeViewDataModel>()); }
            set
            {
                _children = value;
                NotifyPropertyChange("Children");
            }
        }
        private void NotifyPropertyChange(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(name));
        }
        #region INotifyPropertyChanged Members

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}

替代单向:

<Window x:Class="WpfApplication9.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:WpfApplication9"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <HierarchicalDataTemplate DataType="{x:Type app:TreeViewDataModel}" ItemsSource="{Binding Children}">
        <TextBlock Text="{Binding DisplayName.Value}" />
    </HierarchicalDataTemplate>
</Window.Resources>
<Grid>
    <TreeView ItemsSource="{Binding TreeObservableCollection}" />
</Grid>