【问题标题】:How do I set a DataTemplate for a WPF TreeView to display all Elements of an List?如何为 WPF TreeView 设置 DataTemplate 以显示列表的所有元素?
【发布时间】:2013-07-18 11:50:25
【问题描述】:

我想在 WPF 中使用 TreeViews 可视化以下数据结构:

class MyDataContext
{
    ICollectionView Outers {get;set;}
    //...
}

class Outer
{
    string Name {get;set;}
    IEnumberable<Inner> Actions {get;set;} 
}


class Inner
{
    string Description {get;set;}
    Command OnClick {get;set;}
}

这是我目前的尝试:

<!-- DataContext is MyDataContext at this  point -->
<TreeView ItemsSource="{Binding Path=Outers}">
    <TreeView.Resources>
        <DataTemplate DataType="{x:Type myns:Outer}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Name}"/>

                <TreeView ItemsSource="{Binding Path=Actions}" >
                    <DataTemplate DataType="{x:Type myns:Inner}">
                        <Button Command={Binding Path=OnClick}>
                            <TextBlock Text="{Binding Path=Description}"/>
                        </Button>
                    </DataTemplate>
                </TreeView>
            </StackPanel>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

由于我收到以下InvalidOperationException

Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.

如果我放弃内部 TreeView 也不例外(当然也没有按钮)。

【问题讨论】:

    标签: c# wpf data-binding treeview datatemplate


    【解决方案1】:

    我使用了 Mateusz 提到的页面 (HierarchicalDataTemplate),在阅读了这个问题的答案后:Bind Collection to StackPanel 我找到了一个符合我要求的解决方案:

    这里的球员(3 级)与球队(2 级)在同一排:

    <TreeView ItemsSource="{Binding League}">
        <!-- Conference template -->
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Teams}">
                <TextBlock Foreground="Red" Text="{Binding Name}" />
                <!-- Team template -->
                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Name}"/>
                            <ItemsControl ItemsSource="{Binding Players}">
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal">
                                        </StackPanel>
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Button Content="{Binding }"/>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </StackPanel>
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
    

    【讨论】:

      【解决方案2】:

      请尝试将 HierarchicalDataTemplate 与 TreeView 一起使用。

      HierarchicalDataTemplate

      【讨论】:

      • 我查看了您提到的网站,但仍然不知道如何将操作作为与“外部”元素位于同一行的按钮。此页面上的示例会将每个按钮放在“Outer”元素下方的新行中。
      【解决方案3】:

      也许这对你有一点帮助;)

      xaml:

          <TreeView ItemsSource="{Binding Outers}">
              <TreeView.ItemTemplate>
                  <DataTemplate>
                      <TreeViewItem ItemsSource="{Binding Actions}" Header="{Binding Name}">
                          <TreeViewItem.ItemTemplate>
                              <DataTemplate>
                                  <Button Command="{Binding Click}" Content="{Binding Name}" />
                              </DataTemplate>
                          </TreeViewItem.ItemTemplate>
                      </TreeViewItem>
                  </DataTemplate>
              </TreeView.ItemTemplate>
          </TreeView>
      

      数据:

      public partial class MainWindow : Window
      {
          public MainWindow()
          {
              InitializeComponent();
      
              DataContext = new MyDataContext();
          }
      }
      
      
      
          class MyDataContext
          {
              public ObservableCollection<Outer> Outers { get; set; }
      
      
              public MyDataContext()
              {
                  Outers = new ObservableCollection<Outer>();
                  Outers.Add(new Outer() { Name = "Herp" });
                  Outers.Add(new Outer() { Name = "Derp" });
              }
          }
      
          class Outer
          {
              public string Name { get; set; }
              public ObservableCollection<Inner> Actions { get; set; }
      
              public Outer()
              {
                  Actions = new ObservableCollection<Inner>();
                  Actions.Add(new Inner { Name = "Test1" });
                  Actions.Add(new Inner { Name = "Test2" });
                  Actions.Add(new Inner { Name = "Test3" });
                  Actions.Add(new Inner { Name = "Test4" });
                  Actions.Add(new Inner { Name = "Test5" });
                  Actions.Add(new Inner { Name = "Test6" });
                  Actions.Add(new Inner { Name = "Test7" });
              }
          }
      
      
          class Inner
          {
              public string Name { get; set; }
              public ICommand OnClick { get; set; }
          }
      

      如果您使用的是命令... 试试这个例子: ICommand

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-26
        • 2020-04-25
        • 2010-10-20
        • 1970-01-01
        • 1970-01-01
        • 2015-06-04
        相关资源
        最近更新 更多