【问题标题】:WPF TreeView how to add TreeViewItem control template for child elements of TreeViewItemWPF TreeView如何为TreeViewItem的子元素添加TreeViewItem控件模板
【发布时间】:2013-03-29 13:57:56
【问题描述】:

如何创建像这样的树视图:

 <TreeViewItem Header="Customers" ItemsSource="{Binding Customers}">
  • 客户
    • 安娜
      • 删除
      • 打开
    • 彼得
      • 删除
      • 打开
    • 安德鲁
      • 删除
      • 打开

我想创建类似这样的子项模板

 <TreeViewItem Header="{Binding Header}">
   <TreeViewItem Header="Delete"/>
   <TreeViewItem Header="Open"/>
 </TreeViewItem>

但它并不能很好地工作,因为我最终拥有带有 datatemplate treeviewitem 的 treeviewitem,但我想覆盖子元素的 controltemplate,而不是父元素。 当然,我想避免我的绑定是 TreeViewItem,也不想用那些静态对象“打开”、“删除”来创建子项。

【问题讨论】:

  • 删除和打开只是动作吗?
  • 是的,这些对于所有树项都是不变的,所以我想在 XAML 中构建它们。这就是为什么我想使用 TreeViewItem 作为 DataTemplate (这显然是错误的,但你明白我的想法)
  • 您真的需要使用 TreeView 还是只是想要类似的项目排列方式?
  • 现有设计使用TreeView。但是在现有的设计中,这些节点是在代码隐藏中构建的。太可怕了。我想改进静态子项目并将其移动到 XAML,而不是在后面的代码中使用 TreeViewItems 填充 TreeView,然后使用字符串比较来识别单击了哪个项目! ;)

标签: c# wpf mvvm treeview treeviewitem


【解决方案1】:

Here 是我读过的关于TreeView 的最好的文章之一。

TreeView.Resources 中,如果删除和打开命令是某个集合的项目,您可以使用不同的DataType 声明多个DataTemplate。 (命令的 TargetType 是 ICommand)。

但您似乎根本不需要 TreeView。 客户是列表的标题。如果您希望它可扩展,请使用 Expander 控制。
那么为每个客户提供一个数据模板就足够了。

<DataTemplate DataType="CustomerTypeName">
    <Expander Header="{Binding CustomerName}">
        <Button Command="{Binding DeleteCustomerCmd}" Content="Delete" Margin="15,0,0,0"/>
        <Button Command="{Binding OpenCustomerCmd}" Content="Open" Margin="15,0,0,0"/>
    <Expander/>
<DataTemplate>

但是在这里你会遇到一些选择突出显示的问题。

public class CommandWrapper
{
    ICommand Command {get;set;}
    string CommandName {get;set;}
}

public class CustomerViewModel
{
    Customer Customer {get;set;}
    IEnumerable<CommandWrapper> Commands {get;}
}

让客户收藏CustomerViewModel。 那么以下 XAML 可以提供帮助:

<TreeView ItemsSource="{Binding ...}">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="TypeHoldingCustomersCollection" 
            ItemsSource="{Binding Customers}">
            <TextBlock Text="Customers"/>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="CustomerViewModel" 
            ItemsSource="{Binding Commands}">
            <TextBlock Text="{Binding Path=Customer.Name}"/>
        </HierarchicalDataTemplate>

        <DataTemplate DataType="CommandWrapper">
            <Button Content="{Binding CommandName}" Command="{Binding Command}"/>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

【讨论】:

  • 我需要把它放在 TreeView 中,因为客户在其他节点的更大树视图中。 ://
  • 好的,我明白了。您还需要命令(删除和打开)作为树节点吗?
  • 我猜是这样,所以它们看起来和其他地方一样,并且具有相同的设计。它们是否是树节点并不重要,但如果它们是,它们应该看起来与所有树相同(我猜)
  • 然后你应该为你的 ViewModel 中的命令创建一些包装器。我会添加一些代码。
  • 谢谢,我明白你的意思了。所以你建议我不能在 TreeView 中使用 TreeViewItem?使用 setter 来实现这一点怎么样?
猜你喜欢
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
  • 2011-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多