There is some XML.

This XML is required to display on the WinForms application.

I see it like this:

XML is read and some basic information is displayed in some data grid. After the user clicks on a line, the form for editing this XML element with attributes opens.

Problems are caused by my positioning ...

How to understand which node to display on the form when you click on a specific line?

How to understand which node to write changes to after closing the form?

If there were unique attributes or all nodes would be unique, then this would not be a particular problem ...

XML itself has some form:

<root> <config> <monitor/> <monitor/> <monitor/> <other/> <other/> </config> <root/> 

Or maybe in .Net something was thought up for me that solves this problem?

  • Each node is a unique object. In addition, if you use XLinq, then each object can be assigned its own annotation . - Pavel Mayorov
  • It turns out I can create something like a key-value dictionary and, based on this, find out the position and get the necessary nodes? - iluxa1810
  • You can do without a dictionary. But if it is easier for you with a dictionary - yes, that’s possible too. - Pavel Mayorov
  • I meant: "Abstract work like a dictionary or not? I can give the nodes a summary, and then refer to the specific node on the summary?" - iluxa1810
  • No, there is a connection in only one direction (you can get an annotation from the element). - Pavel Mayorov

2 answers 2

Here you are, study. Master finally the data binding.

 using System.Data; using System.Linq; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { //InitializeComponent(); Width = 500; var dataSet = new DataSet(); dataSet.ReadXml("test.xml"); var bindingSource = new BindingSource(); bindingSource.DataSource = dataSet; var dataGridView = new DataGridView { Parent = this, Dock = DockStyle.Top }; dataGridView.DataSource = bindingSource; var editButton = new Button { Parent = this, Top = 200, Left = 200, Text = "Edit", Enabled = false }; editButton.Click += (s, e) => { var editForm = new EditForm(bindingSource); editForm.ShowDialog(); bindingSource.ResetCurrentItem(); }; var tablesComboBox = new ComboBox { Parent = this, Top = 200 }; tablesComboBox.DataSource = dataSet.Tables.OfType<DataTable>().Select(dt => dt.TableName).ToList(); tablesComboBox.SelectedIndexChanged += (s, e) => { string tableName = tablesComboBox.SelectedItem.ToString(); bindingSource.DataMember = tableName; editButton.Enabled = dataSet.Tables[tableName].Columns.Count != 1; }; } } public class EditForm : Form { public EditForm(BindingSource bindingSource) { var tableLayoutPanel = new TableLayoutPanel { Parent = this, Dock = DockStyle.Top, ColumnCount = 2, AutoSize = true }; var okButton = new Button { Parent = this, Text = "OK", DialogResult = DialogResult.OK, Left = 200, Top = 220 }; var dataSet = (DataSet)bindingSource.DataSource; foreach (DataColumn column in dataSet.Tables[bindingSource.DataMember].Columns) { if (!column.ColumnName.EndsWith("_Id")) { var label = new Label { Parent = tableLayoutPanel, Text = column.ColumnName }; var textBox = new TextBox { Parent = tableLayoutPanel, Top = 200, Left = 150 }; textBox.DataBindings.Add("Text", bindingSource, column.ColumnName); } } } } } 

As data uses xml of the form:

 <root> <config> <monitor price="1000" width="1280" height="768" /> <monitor price="1500" width="1440" height="800" /> <monitor price="2000" width="1600" height="900" /> <other price="20" feature="2" /> <other price="30" feature="3" /> </config> </root> 

The number of nodes and attributes is arbitrary, as well as their names.

    The edit form should be opened by passing the node selected for editing to it in the constructor - XmlNode. The form is something like this:

     class XmlNodeEditForm : Form { XmlNode _nodeEdited; protected XmlNodeEditForm() { } protected XmlNodeEditForm(XmlNode nodeEdited) { _nodeEdited = nodeEdited; initEditNodeForm(); } void initEditNodeForm() { Text = _nodeEdited.Name; // кидаем на форму имена и значения атрибутов foreach (XmlAttribute a in _nodeEdited.Attributes) { this.Controls.Add(new Label() { Text = string.Format("{0}:", a.Name), Dock = DockStyle.Top }); this.Controls.Add(new TextBox() { Name = a.Name, Text = a.Name, Dock = DockStyle.Top }); } } protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { // сохраняем перед закрытием foreach (Control c in this.Controls) if (c is TextBox) _nodeEdited.Attributes[c.Name].Value = c.Text; base.OnClosing(e); } } 

    when the user selects an item, the edit form should be called

     (new XmlNodeEditForm(selectedNode)).ShowDialog(); // здесь, после закрытия формы, нужно не забыть обновить отображение XML-узла для пользователя