【问题标题】:TreeView, HierarchicalDataTemplate and recursive DataTreeView、HierarchicalDataTemplate 和递归数据
【发布时间】:2013-02-20 19:54:30
【问题描述】:

对于我的树视图,我有两个不同的类提供 ItemsSource。

public class TreeViewModel : ViewModelBase
{
    public ObservableCollection<NodeViewModel> Items { get; set; }
}

public class NodeViewModel : ViewModelBase
{
    public string Id { get; set; }
    public string Name { get; set; }
    public ObservableCollection<NodeViewModel> Children { get; set; }
}

现在我希望我的 TreeView 显示 TreeViewModel 中的项目并显示 NodeViewModel 提供的分层数据。

这是我的 XAML

<Window x:Class="TreeViewMasterDetails.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TreeViewMasterDetails" 
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TreeView Height="Auto" 
                  HorizontalAlignment="Stretch" 
                  Margin="10" 
                  VerticalAlignment="Stretch" 
                  Width="Auto">
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="x:Type local:TreeViewModel" ItemsSource="{Binding Items}">
                    <TextBlock Text="{Binding Path=Name}"></TextBlock>
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="x:Type local:NodeViewModel" ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Name}"></TextBlock>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
    </Grid>
</Window>

已尝试提供Items 作为TreeViewItemsSource。 如果显示任何内容,它不会分层显示数据。

我也尝试使用ItemTemplate 而不是TreeView.Resources

这有什么问题?

也许是第一个TextBlock Text Binding有问题? 我想在Items那里显示NodeViewModelName属性。

【问题讨论】:

  • 我认为这是 [WPF TreeView HierarchicalDataTemplate - 绑定到具有多个子集合的对象][1] 的副本。 [1]:stackoverflow.com/questions/1912481/…
  • 是的,我已经看到了。但在这里不起作用。
  • 请查看我更新的问题
  • TreeViewModel 没有 Name 属性,但这可能不是问题
  • 在 Windows Phone 上这样做有什么运气吗?

标签: c# wpf treeview hierarchicaldatatemplate


【解决方案1】:

您只需为NodeViewModel 声明HierarchicalDataTemplate,因为这是TreeView 中唯一显示的内容,并将实际的ItemSource 绑定到TreeView

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

完整示例

Xaml:

<Window x:Class="WpfApplication13.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication13"
        Title="MainWindow" x:Name="UI" Width="343" Height="744.625" >

    <TreeView DataContext="{Binding ElementName=UI, Path=TreeModel}" ItemsSource="{Binding Items}">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type local:NodeViewModel}" ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding Name}"></TextBlock>
            </HierarchicalDataTemplate>
        </TreeView.Resources>
    </TreeView>

</Window>

代码:

public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();
    }

    public TreeViewModel TreeModel
    {
        get
        {
            return new TreeViewModel
            {
                Items = new ObservableCollection<NodeViewModel>{
                           new NodeViewModel { Name = "Root", Children =  new ObservableCollection<NodeViewModel> {
                              new NodeViewModel { Name = "Level1" ,  Children = new ObservableCollection<NodeViewModel>{ 
                                  new NodeViewModel{ Name = "Level2"}}} } }}
            };
        }
    }
}

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

public class NodeViewModel
{
    public string Id { get; set; }
    public string Name { get; set; }
    public ObservableCollection<NodeViewModel> Children { get; set; }
}

结果:

【讨论】:

  • 是的,它有效。确定我以前尝试过。非常感谢!
  • 您好,感谢分享,我使用了您的解决方案,但它似乎并没有让我选择任何选项,而且左侧的箭头也不见了。树看起来结冰了。我对您的代码所做的一项更改是,我将 TreeModel 从我的 ViewModel 类而不是从 MainWindow 绑定。
  • 对我来说效果很好。如果您想要传播的复选框而不是文本块,另请参阅stackoverflow.com/questions/2251260
【解决方案2】:

正如@sa_ddam213 所说,您只需要NodeViewModelHierarchicalDataTemplate,但您的代码的唯一问题是数据模板定义中DataType="x:Type local:TreeViewModel" 缺少大括号({})(它应该是DataType="{x:Type local:TreeViewModel}")。添加括号和ItemsSource绑定即可解决问题:

TreeViewModel 的附加HierarchicalDataTemplate 没有使用,但不会造成伤害。

【讨论】:

  • 你是对的,这确实是问题所在。奇怪的是,它在ItemTemplate 中使用时可以不使用大括号,但在Resources 中则不行。
  • @MareInfinitus 是因为使用 int ItemTemplate 时,不需要查看DataType 属性。您是直接对TreeView 说使用给定的项目模板。所以不需要DataType
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多