【问题标题】:How can I get the node level in a treeView?如何在 treeView 中获取节点级别?
【发布时间】:2011-08-16 17:38:22
【问题描述】:

我正在使用来自另一个网站的代码:

How can I model this class in a database?

我在每个目标记录中都有一个名为“Rank”的字段。它告诉我什么位置。例如:

Objective "Geometry": Rank1
|_Objective "Squares": Rank1
|_Objective "Circles": Rank2
|_Objective "Triangle": Rank3
  |_Objective "Types": Rank1
Objectve "Algebra": Rank2
Objective "Trigonometry": Rank3

该等级告诉我节点的顺序。但我想获得所有排名:第三名将是:

Objective "Geometry": Rank1
|_Objective "Squares": Rank1   -> 1.1
|_Objective "Circles": Rank2
|_Objective "Triangle": Rank3
  |_Objective "Types": Rank1   -> 1.3.1
Objectve "Algebra": Rank2
Objective "Trigonometry": Rank3    -> 3

我正在使用 LINQ to SQL。我该怎么做?

    <TreeView Name="treeView1">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate DataType="{x:Type data:Objective}" ItemsSource="{Binding Path=Objectives}" >
                <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

【问题讨论】:

  • 我建议你通过一些递归方法在模型中(而不是在视图/GUI中)解决这个问题。
  • 有关设置级别的递归函数的示例,请参见:stackoverflow.com/questions/6225123/…

标签: c# wpf database linq-to-sql treeview


【解决方案1】:

我不确定我是否理解您想要什么,但是递归地遍历树并为对象分配等级非常简单。这是我编写的一些快速代码:

    public void Test()
    {
        Objective math = Init();
        RankObjective("", math);
        System.Console.ReadLine();
    }

    private void RankObjective(string rank, Objective objective)
    {
        int count = 1;
        if (!String.IsNullOrEmpty(rank))
            Console.WriteLine(objective.Name + ": " + rank);
        foreach (Objective child in objective.Objectives)
        {
            string newRank = String.IsNullOrEmpty(rank) ? count.ToString() : rank + "." + count.ToString();
            RankObjective(newRank, child);
            count++;
        }
    }

    private Objective Init()
    {
        Objective math = new Objective("Math");
        Objective geometry = new Objective("Geometry");
        geometry.Objectives.Add(new Objective("Squares"));
        geometry.Objectives.Add(new Objective("Circles"));
        Objective triangle = new Objective("Triangle");
        triangle.Objectives.Add(new Objective("Types"));
        geometry.Objectives.Add(triangle);
        math.Objectives.Add(geometry);
        math.Objectives.Add(new Objective("Algebra"));
        math.Objectives.Add(new Objective("Trigonometry"));
        return math;
    }

使用这个类:

public class Objective
{
    public Objective(string name)
    {
        Name = name;
        Objectives = new List<Objective>();
    }

    public string Name { get; set; }
    public List<Objective> Objectives { get; set; }
}

输出:

Geometry: 1
Squares: 1.1
Circles: 1.2
Triangle: 1.3
Types: 1.3.1
Algebra: 2
Trigonometry: 3

【讨论】:

    【解决方案2】:

    从以下内容开始:

    void main()
    {
        foreach(Node root in nodeCollection)
        {
            this.Recursion(root, 1);
        }
    }
    
    void Recursion(Node n, int depth)
    {
        node.Depth = depth;
        foreach(Node child in n.Children)
        {
            this.Recursion(child, depth++);
        }
    }
    

    这将为您提供每个节点的深度(当然您必须将字段节点添加到您的类中)。

    【讨论】:

      【解决方案3】:

      到目前为止,最简单的实现方法是在模型或视图模型中。例如,在您的 Node 类中,您可以实现以下属性:

      public Collection<Node> Siblings { /* see below */ }
      
      public Collection<Node> Children { get; set; }
      
      public Node Parent { get; set; }
      
      public int Position 
      { 
         get 
         { 
            return (Parent == null) 
               ? 0  // I don't like magic numbers, but I don't want to make this an int? either
               : Siblings.IndexOf(this) + 1; 
         }
      }
      
      public string Rank
      {
          get
          {
             return (Parent == null)
                ? Position.ToString()
                : Parent.Rank + "." + Position.ToString();
          }
      }
      

      通常,实现Siblings 属性的最简单方法是

      public Collection<Node> Siblings 
      { 
         get 
         { 
            return (Parent == null)
               ? null
               : Parent.Children;
         }
      }
      

      这在存在不属于节点层次结构的顶级节点集合的情况下不起作用,就像这样。您可以通过创建一个不会出现在您的 UI 中的根 Node 对象来实现这一点 - 在这种情况下,您可以将 TreeView 绑定到根节点的 Children 属性,并像这样实现 Rank

      public string Rank
      {
          get
          {
             if (Parent == null)
             {
                return null;
             }
             if (Parent.Parent == null)
             {
                return Position.ToString();
             }
             return Parent.Rank + "." + Position.ToString();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-14
        相关资源
        最近更新 更多