在Winform中公开对象以进行编辑的最佳方法?

时间:2019-04-24 15:05:28

标签: winforms clr

我有一个来自反序列化XML的对象。 我想对其进行可视化并使其可从UI中进行编辑。 一开始这似乎很容易,但是随着我深入研究它变得越来越混乱。

我的第一种方法是使用拆分面板: -在左侧是TreeView。 -在右侧,是一个ListView,显示在TreeView中选择的值/对象。

问题是我不知道如何将所有内容(列表和树)与对象链接。 我通过遍历对象中的每个元素来填充TreeView。

编辑:是否可以在CLR中实现。除此以外,我还需要使用一些C ++代码。

1 个答案:

答案 0 :(得分:0)

因此,您有一个显示TreeNode的TreeView对象,其中每个TreeNode都显示一个System.Xml.XmlNode。每个TreeNode的(子)节点与XmlNode的子级相对应。

您必须决定要为XmlNode显示什么文本,但这是一个小问题。

class XmlTreeNode : System.Windows.Forms.TreeNode
{
     public XmlTreeNode(System.Xml.XmlNode xmlNode) : base()
     {
         this.XmlNode = xmlNode;
         string textToDisplay = xmlNode.ToDisplayText();
         this.Text = textToDisplay;

         foreach (var childXmlNode in xmlNode.xmlNodeList.Cast<XmlNode>())
         {
              XmlTreeNode childNode = new XmlTreeNode(childXmlNode);
              this.Nodes.Add(childNode);
         }
    }
    public XmlNode XmlNode {get; private set;}
}

当然,XmlNode没有方法ToDisplayText(),因此让我们为其创建扩展功能。参见extension methods demystified

static string ToDisplayText(this System.Xml.XmlNode xmlNode)
{
    // TODO: what would you like to Display?
    return xmlNode.Name;
}

当然,您希望能够在XmlTreeNodeView中显示这些XmlTreeNode:

class XmlTreeNodeView : System.Windows.Forms.TreeView
{
     // default constructor: constructs empty XmlTreeNodeView:
     public XmlTreeNodeView() : base() {}

     // constructor fills the XmlTreeNodeView with the XmlNodes:
     public XmlTreeNodeView(IEnumerable<XmlNode> xmlNodes) : base()
     {
         foreach (XmlNode xmlNode in xmlNodes)
         {
             this.Nodes.Add(new XmlTreeNode(xmlNode));
     }
}

当然,您希望在节点之一被单击时得到通知

public class XmlTreeNodeEventArgs : EventArgs
{
    public XmlNode XmlNode {get; set;}
}

在您的XmlTreeView类中:

public event EventHandler<XmlTreeNodeEventArgs> XmlNodeClicked;

protected virtual void OnXmlNodeClicked(XmlNode node)
{
    return XmlNodeClicked?.Invoke(new XmlTreeNodeEventArgs() {XmlNode = node});
}

protected override void OnAfterSelect (System.Windows.Forms.TreeViewEventArgs e)
{
    // get the XmlTreeNode that was clicked:
    XmlTreeNode node = (XmlTreeNode)e.Node;
    this.OnXmlNodeClicked(node);        
}

令人高兴的是,您必须做一些愚蠢的事情才能在XmlTreeView中获得XmlNodes之外的其他东西。

如果您确实想防止添加不同于XmlNode的内容,则XmlTreeView不应继承自TreeView,而应继承自UserControl。 UserControl应该在其中显示一个TreeView。尽管此方法有效,但您必须复制要公开的所有TreeView功能。我不确定您的XmlTreeView仅包含XmlTreeNodes还是需要额外的安全性。