C# WPF 元素的递归重复嵌套层次结构

问题描述 投票:0回答:1

我已经创建了从 xml 文件层次结构动态填充的树视图,但我遇到了问题。在树视图中,嵌套层次结构是递归重复的,并得到如下结果:

enter image description here

树视图的 XAML 标记:

<TreeView x:Name="leftNestingTreeView" ItemsSource="{Binding Fragments, UpdateSourceTrigger=PropertyChanged}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding ChildFragments}" DataType="{x:Type a:FragmentModel}">
            <TextBlock  Text = "{Binding fragmentId}"/>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

来源代码:

Fragments = NestingTree.Values.ToList();
OnPropertyChanged(nameof(Fragments));

XML 文件:

<NestingTree>
  <fragment id="root_fragment" name=" n1">
    <parent id="" name="" />
    <childs count="1">
      <child id="f1" name="frag1" />
    </childs>
  </fragment>
    <fragment id="f1" name="frag1">
    <parent id="root_fragment" name="n1" />
    <childs count="1">
      <child id="f2" name="frag2" />
    </childs>
  </fragment>
  <fragment id="f2" name="frag2">
    <parent id="f1" name="frag1" />
    <childs count="0" />
  </fragment>
</NestingTree>

更新

NestingTree 是 Dictionary,其中键是 ids,值是片段。

FragmentModel代码:

public class FragmentModel 
{
    public string fragmentId { get; set; }    
    private string fragmentName { get; set; }    
    public string FragmentName
    {
        get { return fragmentName; }
        set 
        { 
           fragmentName = value; 
           OnPropertyChanged(nameof(FragmentName)); 
        }
     }
     public FragmentModel ParentFragment { get; set; }
     public List<FragmentModel> ChildFragments { get; set; }                   
     public event PropertyChangedEventHandler PropertyChanged;
     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
     {
        if (PropertyChanged != null)
        {
            PropertyChanged?.Invoke(this, new 
            PropertyChangedEventArgs(propertyName));
        }
     }
}

从 XML 文件填充 NestingTree 数据:

XDocument xmlNestingTree = XDocument.Load("nesting_tree.xml");
if (xmlNestingTree.Element("NestingTree") is not null)
{
   int count = 0;
   foreach (XElement fragment in 
    xmlNestingTree.Element("NestingTree").Elements("fragment"))
   {
       string id = fragment.Attribute("id").Value;
       FragmentModel f = new FragmentModel
       {
           fragmentId = id,
           FragmentName = fragment.Attribute("name").Value,
       };
       nestingTree.Add(id, f);
   }
   foreach (XElement fragment in 
     xmlNestingTree.Element("NestingTree").Elements("fragment"))
   {
        FragmentModel currentFragment = nestingTree.Values.Where(f => f.fragmentId == fragment.Attribute("id").Value).FirstOrDefault();
        FragmentModel parentFragment = nestingTree.Values.Where(f => f.ChildFragments.Contains(currentFragment)).FirstOrDefault();
        currentFragment.ParentFragment = parentFragment; 
        if (Int32.TryParse(fragment.Element("childs").Attribute("count").Value, out count) && count > 0)
        {
            foreach (XElement child in fragment.Element("childs").Elements("child"))
            {
                FragmentModel currentChildFragment = nestingTree.Values.Where(f => f.fragmentId == child.Attribute("id").Value).FirstOrDefault();  
                currentFragment
                    .ChildFragments
                    .Add(currentChildFragment);
            }
        }
    }
    NestingTree = nestingTree;
}
c# wpf treeview hierarchicaldatatemplate
1个回答
0
投票

保存树数据的可能方法有:

  • 存储项目的线性列表,其中每个项目包含“parent_id”属性 或
  • 直接在每个元素中存储子元素列表。 您的 xml 同时使用这两种方法。 我建议删除“parent_id”(代码将递归读取每个 xml 元素并构建树) 或者 删除“子项”(在这种情况下,代码将读取所有元素以按级别列出和构建树,首先搜索没有父项的根片段,然后按喜欢列表循环并搜索父项是当前项的片段等)。
© www.soinside.com 2019 - 2024. All rights reserved.