这个 TreeView 和分层数据绑定有什么问题?

What is wrong with this TreeView and Hierarchical data binding?

更新 请参阅 Simplifying the WPF TreeView ... 了解此实现。

从底部开始:

我有一个封装 BuildItemVM 的视图模型 ProjectExplorerVMBuildItemVM 迭代 Folders:

的嵌套结构
public event PropertyChangedEventHandler PropertyChanged;

public ObservableCollection<BuildItemVM> Folders {
    get { return folders; }
}

#region constructor
public BuildItemVM(Build Build) : this(Build.RootFolder, null) {
    Name = Build.Name;
}

private BuildItemVM(Folder childFolder, BuildItemVM parentFolder) {
    folderItem = childFolder;
    parentItem = parentFolder;
    Name = folderItem.Name;

    folders = new ObservableCollection<BuildItemVM>(childFolder.Folders
        .Select(f => new BuildItemVM(f, this)));
    folders.CollectionChanged += FoldersCollectionChanged;
}
#endregion

ProjectExplorerVM如下:

    #region properties

    public event PropertyChangedEventHandler PropertyChanged;


    public ReadOnlyCollection<BuildItemVM> RootItems {
        get;
        private set;
    }
    #endregion


    #region constructor
    public ProjectExplorerVM(Build BuildProject) {
        build = BuildProject;
        buildItemVM = new BuildItemVM(build);

        buildItemVM.Folders.CollectionChanged += FoldersCollectionChanged;

        RootItems = new ReadOnlyCollection<BuildItemVM>(new BuildItemVM[] { buildItemVM });
    }
    #endregion

... 好吧,我已经尝试了很多我在 google 机器上发现的不同东西。这是我在 XAML:

中尝试绑定的内容
    <TreeView Name="BuildTree" 
              HorizontalAlignment="Stretch"
              VerticalAlignment="Stretch">
        <TreeView.Resources>
            <build:BuildFolder x:Key="FolderList"/>

            <HierarchicalDataTemplate DataType="{x:Type build:BuildFolder}"
                                      ItemsSource="{Binding Path=Folders}">
                <TextBlock Text="{Binding Path=Name}"/>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type build:Project}"
                                      ItemsSource="{Binding Path=Folders}">
                <TextBlock Text="{Binding Path=Name}"/>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type build:Solution}"
                                      ItemsSource="{Binding Path=Folders}">
                <TextBlock Text="{Binding Path=Name}"/>
            </HierarchicalDataTemplate>
        </TreeView.Resources>
        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                <Setter Property="FontWeight" Value="Normal" />
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="FontWeight" Value="Bold" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TreeView.ItemContainerStyle>
        <TreeViewItem ItemsSource="{Binding Source={StaticResource FolderList}}"/>
    </TreeView>

TreeView 控件中没有出现任何节点。我的绑定有什么问题?

原来我在绑定中使用了不正确的 属性 名称。所以我发布了正确的绑定 (Xaml):

                <TreeView Name="BuildTree"
                          ItemsSource="{Binding RootItems}">
                    <TreeView.ItemContainerStyle>
                        <Style TargetType="{x:Type TreeViewItem}">
                            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                            <Setter Property="FontWeight" Value="Normal" />
                            <Style.Triggers>
                                <Trigger Property="IsSelected" Value="True">
                                    <Setter Property="FontWeight" Value="Bold" />
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </TreeView.ItemContainerStyle>

                    <TreeView.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Folders}">
                            <TextBlock Text="{Binding Name}" />
                        </HierarchicalDataTemplate>
                    </TreeView.ItemTemplate>
                </TreeView>