Windows Forms TreeView - 绑定层次递归数据源

3

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

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

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 Forms中,不可能关联一种类型的数据源,它是任意类型的集合(实现IEnumerable)。 除了使用第三方组件,我该怎么解决我的问题呢。 我在WinForms上的经验很短暂,并且当我学会更好地管理WPF时,他们决定转移它 :(

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

更新2:: 填充treeView的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)移动到另一个。 它们都是2个选项卡的一部分,是TabControl的子级。


所有的评论呢?O_o'' - DioBrando
1
已经过去了4天,没有人能回答这个问题?我想知道所有的winforms专家都躲在哪里...我刚刚开启了一个悬赏。以便让你意识到所有可能的答案都需要大量不必要的代码支持,而且你真的不应该从21世纪的WPF切换回可怕的陈旧的winforms时代。 - Federico Berasategui
我已经自己完成了,但感谢你的关心。 顺便说一下,这并不需要很多代码,那更多是设计问题。 谢谢你50+ :) - DioBrando
2
好的,如果你已经解决了这个问题,要么删除这个问题,要么发布一个答案。我仍然在努力理解为什么有人会从WPF回到winforms... - Federico Berasategui
4
这是一个方法,用于获取树形结构的节点,并返回树形结构节点的数组。方法需要一个包含TreeViewNode元素的列表作为参数。在方法内部,它遍历传入的节点列表,创建TreeNode对象并将其添加到另一个节点列表中,最后将该节点列表转换为TreeNode数组并返回。对于每个节点,它使用该节点的Text属性创建一个新的TreeNode对象,并使用递归调用GetTreeViewNodes方法来为该节点的子节点创建TreeNodes。此外,还会将节点的DocKey设置为新创建的TreeNode对象的标记属性。 - DioBrando
1
以下是关于编程的内容,请将其从英语翻译成中文,只需翻译文本内容,不必进行解释。 - Federico Berasategui
1个回答

1

(由问题编辑者回答。已转换为社区wiki答案。请参见没有答案的问题,但在评论中解决了问题(或在聊天中扩展))

原帖作者写道:

实际上我自己想到了这个。思路是通过递归创建一个TreeNode,从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));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接