【问题标题】:Best way to expose an object in winform for editing?在winform中公开对象以进行编辑的最佳方法?
【发布时间】:2019-09-13 22:31:41
【问题描述】:

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

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

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

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

【问题讨论】:

  • 我不知道是否需要使用 Winforms,但我建议使用 WPF(通常和),特别是对于这个用例。遵循此建议时,请搜索“Master Detail Scenario”。 //编辑:或从这个例子开始:wpf-tutorial.com/listview-control/…
  • 你能比“一个对象”更具体吗?您的 XML 是什么,您想要可视化和编辑什么?你的用户界面是什么? “将所有内容(列表和树)与对象联系起来”是什么意思?为什么您认为这会有所帮助?

标签: winforms clr


【解决方案1】:

所以你有一个显示 TreeNodes 的 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 的额外安全成本。

【讨论】:

  • 谢谢哈拉德。这是一个非常完整的答案,我相信您花了一些时间,所以我会尝试检查它。但我编辑了我的问题,指出我需要在 CLR 中执行此操作,我不太习惯,因此我会尝试调整您的代码并提供一些反馈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
  • 2011-11-25
  • 2018-10-06
  • 1970-01-01
  • 2013-12-12
  • 2013-07-20
相关资源
最近更新 更多