Windows 窗体树视图 - 绑定分层递归数据源

本文关键字:分层 递归 数据源 绑定 窗体 视图 Windows | 更新日期: 2023-09-27 18:36:17

我正在 Windows 窗体中转换 WPF 客户端,但在尝试复制 TreeView 控件结构时遇到了一些问题。

在第一个项目中,我有一个自定义工厂,它构建了一个从基本上是 XML 的输入字符串开始的结构。返回类型是集合。自定义树节点:

public class TreeViewNode
{
    public TreeViewNode() { }
    public DocumentKey DocKey { get; set; }
    public string Text { get; set; }
    public IList<TreeViewNode> Children { get; set; }
}

厂:

public class TreeViewFactory
{
    public IList<TreeViewNode> GetSctructure(DocumentKey docKey, string structure, bool loadAllParents)
    {
        XDocument xmlDocstructure = CommonXmlValueParser.GetXDocument(structure);
        var parentsNodes = (from item in xmlDocstructure.Descendants("structure_item")
                            where (CommonXmlValueParser.GetAttribute(item, "level") == "1")
                            select new TreeViewNode
                            {
                                Text = GetNodeText(item),
                                DocKey = new DocumentKey()
                                {
                                    Bank = docKey.Bank,
                                    Ud = int.Parse(CommonXmlValueParser.GetElement(item.Element("ud"))),
                                    Master = int.Parse(CommonXmlValueParser.GetElement(item.Element("master"))),
                                    NVig = int.Parse(CommonXmlValueParser.GetElement(item.Element("nvig"))),
                                    Subjects = docKey.Subjects
                                },
                                Children = GetChildrenNodes(item, 2, docKey.Bank)
                            }).ToList();
        return parentsNodes;
    }

    private IList<TreeViewNode> GetChildrenNodes(XElement element, int level, int dataBank)
    {
        var childrenNodes = (from item in element.Descendants("structure_item")
                             where (CommonXmlValueParser.GetAttribute(item, "level") == level.ToString())
                             select new TreeViewNode
                             {
                                 Text = GetNodeText(item),
                                 DocKey = new DocumentKey()
                                 {
                                     Bank = dataBank,
                                     Ud = int.Parse(CommonXmlValueParser.GetElement(item.Element("ud"))),
                                     Master = int.Parse(CommonXmlValueParser.GetElement(item.Element("master"))),
                                     NVig = int.Parse(CommonXmlValueParser.GetElement(item.Element("nvig"))),
                                 },
                                 Children = GetChildrenNodes(item, level + 1, dataBank)
                             }).ToList();
        return childrenNodes;
    }
}

捆绑:

void CreateTree(object tree, EventArgs e)
{
    //...
    TreeViewFactory treeFactory = new TreeViewFactory();
    var documentStructure = treeFactory.Structure(document.DocumentKey, document.XmlStructure, true);
    this.tabMainControl.document.SetTreeViewStructureNodes(documentStructure);
}
public void SetTreeViewStructureNodes(IList<TreeViewNode> nodes)
{ 
    this.treeView.ItemsSource = nodes;
}

更新:

我使 TreeViewNode

从 TreeNode 派生,并在以下位置更改了方法SetTreeViewStructureNodes:

private TreeView SetTreeViewStructureNodes(IList<TreeViewNode> nodes)
{
    TreeView treeView = new TreeView();
    treeView.Nodes.AddRange(nodes.ToArray());
    return treeView;
}

这仍然没有实现我的目标,因为它仍然没有渲染......

据我所知,在Windows窗体中,不可能关联一种数据类型集合(实现IEnumerable)。除了使用第三方组件,我如何解决我的问题。我在WinForms上的经验很短,当我学会更好地管理WPF时,他们决定将其转移到:(

感谢您的所有帮助,问候。

更新2:填充树视图的WinForms用户控件片段:

TreeView treeView = (TreeView)documentViewControl.Controls["treeViewStructure"];

TreeViewFactory treeFactory = new TreeViewFactory();
var documentStructure = treeFactory.GetStructure(document.DocumentKey, document.XmlStructure, true);
treeView = this.SetTreeViewStructureNodes(documentStructure);

基本上,我正在从一个UC转移到另一个UC。它们都是 2 个选项卡的一部分,是 TabControl 的子项。

Windows 窗体树视图 - 绑定分层递归数据源

(由OP作为问题编辑回答。 转换为社区维基答案。请参阅没有答案的问题,但问题在评论中得到解决(或在聊天中扩展) )

OP写道:

其实我自己得到了。这个想法是改变递归的想法,从TreeViewNodes的集合(IList)创建一个TreeNode。问题 1:递归 问题 2:如何维护 DocKey 自定义属性

private TreeNode[] GetTreeViewNodes(IList<TreeViewNode> nodes)
{
    IList<TreeNode> returnedNodes = new List<TreeNode>();
    foreach (var item in nodes)
    {
        TreeNode node = new TreeNode(item.Text, this.GetTreeViewNodes(item.Children));
        node.Tag = item.DocKey;
        returnedNodes.Add(node);
    }
    return returnedNodes.ToArray();
}

树视图所需的代码变为:

this.treeView.Nodes.Clear();
this.treeView.Nodes.AddRange(this.GetTreeViewNodes(documentStructure));