为什么TreeView Control不绑定

时间:2018-06-21 13:03:13

标签: c# wpf mvvm data-binding treeview

这是我的模特:

public class TreeItem : INotifyPropertyChanged
{
    private ObservableCollection<TreeItem> _items;
    private string _fullPath;
    private string _name;

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

    public string FullPath
    {
        get
        {
            return _fullPath;
        }
        set
        {
            _fullPath = value;
            OnPropertyChanged("FullPath");
        }
    }

    public ObservableCollection<TreeItem> Items
    {
        get
        {
            return _items;
        }
        set
        {
            _items = value;
            OnPropertyChanged("Items");
        }
    }

    public TreeItem(string name)
    {
        Name = name;
        Items = new ObservableCollection<TreeItem>();
    }

    public TreeItem()
    {
        Items = new ObservableCollection<TreeItem>();
    }


    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName]string prop = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}

我实现INotifyPropertyChanged,因为我认为通过添加此实现可以解决该问题。所以有我的Xaml TreeView:

<TreeView Name="FileFolderTree" Grid.Column="2" Grid.Row="2" Background="DarkGray" ItemsSource="{Binding FolderFiles}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type model:TreeItem}" ItemsSource="{Binding Path=Items}">
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

这是MainWindow.cs,其DataContext等于新的MainWindowViewModel:

public MainWindow()
{
    InitializeComponent();
    DataContext = new MainWindowViewModel();
}

因此,MainWindowViewModel具有公共属性:

private  TreeItem _folderFiles;

public TreeItem FolderFiles {
    get
    {
        return _folderFiles;
    }
    set
    {
        _folderFiles = value;
        OnPropertyChanged("FolderFiles");
    }
}

在某些方法中,我看到_folderFiles包含数据,但未在treeView上显示。如果我要对treeView中的某些元素进行硬编码,将显示它们。

我不正确地做什么?

1 个答案:

答案 0 :(得分:2)

您的问题在这里:

public TreeItem FolderFiles 
{
    get
    {
        return _folderFiles;
    }
    set
    {
        _folderFiles = value;
        OnPropertyChanged("FolderFiles");
    }
}

此属性的类型为TreeItem,但是您正在尝试将其用于TreeView.ItemsSource属性的绑定中。该属性需要一个IEnumerable对象。如果您查看“调试输出”窗口,则会在此处发现“数据错误”,因为绑定无法提供正确的值。

将您的媒体资源更改为IEnumerable<TreeItem>

创建一个ObservableCollection<TreeItem>作为根容器:

public ObservableCollection<TreeItem> FolderFiles { get; } = new ObservableCollection<TreeItem>();

//...

FolderFiles.Add(_folderFiles);

如果只希望有一个根元素,则可以执行以下操作:

private TreeItem _folderFiles;
public IEnumerable<TreeItem> FolderFiles => new[] { _folderFiles };

(请注意,此示例不支持INotifyPropertyChangedINotifyCollectionChanged,但是您可以肯定地实现。)