2015-10-20 88 views
-1

我一直在浏览教程和阅读一些关于树视图中多种类型的文章。不过,我还没有遇到过一个教程,它解释了如何构建或处理一个包含多个嵌套的不同节点类型的treeview。例如,考虑一个典型的文件夹结构。一个文件夹可以包含文件和文件夹,其中的文件夹可以包含更多的文件和文件夹。所以我试图把它分解成一个简单的解决方案,希望有人能够修改/向我解释如何让一个家庭嵌套在另一个家庭内,如下图所示。到其他堆栈溢出的链接并不能解释INode接口如何工作的细节。与多种类型的WPF树视图

enter image description here

从我读过什么,我知道我需要三个等级。

  1. 第1类:FamilyNode

    • 这个类包含3名属性成员名,父
  2. 二级:FamilyMember

    • 这个类包含2个属性名称,年龄
  3. 3类:INODE

    • 这个类包含1个属性名称。为这个类创建一个INode接口将允许我们在Treeview中创建您想要的每个内容项的不同实现。这个类的一个例子就是喜欢这样。我相信

public interface INode 
{ 
    string Name { get; } 
    string Path { get; } 
} 

下面是什么在上面下的“当前”图片中看到的代码。我知道这不是以最好的方式组织起来的,我只是希望得到一个简单的例子和​​解释。我希望你们能够提供帮助,它为此耗费时间进行研究。我只能围绕如何制作可能是Family或FamilyMember类型的节点集合,然后开始构建树视图。谢谢你们的帮助。

ViewModel.cs

using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Runtime.CompilerServices; 

    namespace WpfApplication1 
    { 
     public class ViewModel : INotifyPropertyChanged 
     { 
      private ObservableCollection<Family> families; 
      public ObservableCollection<Family> Families 
      { 
       get { return families; } 
       set 
       { 
        families = value; 
        NotifyPropertyChanged("Families"); 
       } 
      } 

      public ViewModel() 
      { 
       // FAMILIES 
       Families = new ObservableCollection<Family>(); 

       Family family1 = new Family() { Name = "The Doe's" }; 
       family1.Members.Add(new FamilyMember() { Name = "John Doe", Age = 42 }); 
       family1.Members.Add(new FamilyMember() { Name = "Jane Doe", Age = 39 }); 
       family1.Members.Add(new FamilyMember() { Name = "Sammy Doe", Age = 13 }); 
       Families.Add(family1); 

       Family family2 = new Family() { Name = "The Moe's" }; 
       family2.Members.Add(new FamilyMember() { Name = "Mark Moe", Age = 31 }); 
       family2.Members.Add(new FamilyMember() { Name = "Norma Moe", Age = 28 }); 
       Families.Add(family2); 
      } 

      public event PropertyChangedEventHandler PropertyChanged; 

      public void NotifyPropertyChanged([CallerMemberName] string propertyName = null) 
      { 
       PropertyChangedEventHandler handler = PropertyChanged; 
       if (handler != null) 
       { 
        handler(this, new PropertyChangedEventArgs(propertyName)); 
       } 
      } 
     } 

     public class Family 
     { 
      public Family() 
      { 
       this.Members = new ObservableCollection<FamilyMember>(); 
      } 

      public string Name { get; set; } 
      public ObservableCollection<FamilyMember> Members { get; set; } 
     } 

     public class FamilyMember 
     { 
      public string Name { get; set; } 
      public int Age { get; set; } 
     } 
    } 

MainWindow.Xaml

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:self="clr-namespace:WpfApplication1" 
     Title="MainWindow" Height="350" Width="305" 
     WindowStartupLocation="CenterScreen"> 

    <Window.DataContext> 
     <self:ViewModel/> 
    </Window.DataContext> 

    <Grid> 
     <TreeView Name="trvFamilies" ItemsSource="{Binding Families}" Grid.Row="1" Grid.ColumnSpan="2"> 
      <TreeView.Resources> 
       <HierarchicalDataTemplate DataType="{x:Type self:Family}" ItemsSource="{Binding Members}"> 
        <StackPanel Orientation="Horizontal"> 
         <Label VerticalAlignment="Center" FontFamily="WingDings" Content="1"/> 
         <TextBlock Text="{Binding Name}" /> 
        </StackPanel> 
       </HierarchicalDataTemplate> 
       <DataTemplate DataType="{x:Type self:FamilyMember}"> 
        <StackPanel Orientation="Horizontal"> 
         <Label VerticalAlignment="Center" FontFamily="WingDings" Content="2"/> 
         <TextBlock Text="{Binding Name}" /> 
        </StackPanel> 
       </DataTemplate> 
      </TreeView.Resources> 
     </TreeView> 
    </Grid> 

</Window> 
+0

我不能为WPF说话,但在的WinForms,你可以将标签分配到每个节点类型,并根据其作用。 –

+0

是的,这并不适用于wpf – JokerMartini

+2

你能解释[这个答案](http://stackoverflow.com/a/33195027/643085)不能满足你的需求吗?在我看来,你在这里提出的一切都已经在你以前的文章中得到了回答。 –

回答

1

我想出的解决方案与朋友交谈,想我会在这里发布。

ViewModel.cs

using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Runtime.CompilerServices; 

namespace WpfApplication1 
{ 
    public class ViewModel : INotifyPropertyChanged 
    { 
     private ObservableCollection<INode> families; 
     public ObservableCollection<INode> Families 
     { 
      get { return families; } 
      set 
      { 
       families = value; 
       NotifyPropertyChanged("Families"); 
      } 
     } 

     public ViewModel() 
     { 
      // FAMILIES 
      Families = new ObservableCollection<INode>(); 

      Family family1 = new Family() { Name = "The Doe's" }; 
      family1.Members.Add(new FamilyMember() { Name = "John Doe", Age = 42 }); 
      family1.Members.Add(new FamilyMember() { Name = "Jane Doe", Age = 39 }); 
      family1.Members.Add(new FamilyMember() { Name = "Sammy Doe", Age = 13 }); 
      Families.Add(family1); 

      Family family2 = new Family() { Name = "The Moe's" }; 
      family2.Members.Add(new FamilyMember() { Name = "Mark Moe", Age = 31 }); 
      family2.Members.Add(new FamilyMember() { Name = "Norma Moe", Age = 28 }); 
      Families.Add(family2); 

      Family family3 = new Family() { Name = "The Dunkin's" }; 
      family3.Members.Add(new FamilyMember() { Name = "Kevin Dunkin", Age = 31 }); 
      family3.Members.Add(new FamilyMember() { Name = "Breana Dunkin", Age = 28 }); 
      family2.Members.Add(family3); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     public void NotifyPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 

    public interface INode 
    { 
     string Name { get; } 
    } 

    public class Family : INode 
    { 
     public Family() 
     { 
      this.Members = new ObservableCollection<INode>(); 
     } 

     public string Name { get; set; } 
     public ObservableCollection<INode> Members { get; set; } 
     public Family Parent { get; private set; } 
    } 

    public class FamilyMember : INode 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 
    } 
}