Лучший способ выставить объект в winform для редактирования? - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть объект из десериализованного XML. Я хочу визуализировать его и сделать его редактируемым из пользовательского интерфейса. Вначале это казалось очень легким, но я все больше запутываюсь, когда углубляюсь в это.

Моим первым подходом было использование разделенной панели: - Слева, TreeView. - Справа ListView, показывающий значение / объект, выбранный в TreeView.

Проблема в том, что я не знаю, как связать все (список и дерево) с объектом. Я заполняю TreeView, просматривая каждый элемент объекта.

Редактировать: возможно ли реализовать в CLR. Мне нужно использовать некоторый код C ++ помимо этого.

1 Ответ

0 голосов
/ 25 апреля 2019

Итак, у вас есть объект TreeView, который показывает TreeNodes, где каждый 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 (), поэтому давайте создадим для этого функцию расширения. См. демистифицированные методы расширения

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

Конечно, вы хотите иметь возможность показывать эти XmlTreeNodes в XmlTreeNodeView:

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);        
}

Приятно то, что вы должны делать довольно глупые вещи, чтобы получить другие вещи, кроме XmlNodes, в вашем XmlTreeView.

Если вы действительно хотите предотвратить добавление чего-то отличного от XmlNode, ваш XmlTreeView должен наследоваться не от TreeView, а от UserControl. UserControl должен показывать TreeView внутри него. Хотя этот метод работает, вам придется скопировать все функции TreeView, которые вы хотите предоставить. Я не уверен, что если дополнительная работа соизмерима со стоимостью дополнительной безопасности, которую ваш XmlTreeView содержит только XmlTreeNodes.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...