从 xml 加载对象,在动态 UI 中编辑值并保存回 xml

Posted

技术标签:

【中文标题】从 xml 加载对象,在动态 UI 中编辑值并保存回 xml【英文标题】:Load object from xml, edit values in a dynamic UI and save back to xml 【发布时间】:2021-04-16 14:34:27 【问题描述】:

我刚刚阅读并将其应用于容器面板上的动态对象、标题的标签、内容的文本框。 但是这里我在文本框中填写数据时无法保存。

这是我的反序列化 xml 代码:

string Location= Path.Combine("D:\\Data\\Code.xml");
XmlDocument doc = new XmlDocument();
doc.Load(lokasiString);
foreach (XmlNode node in doc.DocumentElement)

    string name = node.Attributes[0].InnerXml;
    string value = node.InnerText;

    // create panel
    Panel panel = new Panel();
    panel.Name = "panelImages";
    panel.Size = new Size((int)(this.Width*0.9), 30);
    panel.Dock = DockStyle.Top;
    panel.BorderStyle = BorderStyle.FixedSingle;

    Label l = new Label();
    l.Text = name;
    l.Font = new Font("Serif", 12, FontStyle.Bold);
    l.ForeColor = Color.Black;
    l.Size = new Size((int)(this.Width * 0.2), 30);
    l.Dock = DockStyle.Left;    
    TextBox tb = new TextBox();
    tb.Text = value;
    tb.Font = new Font("Serif", 12, FontStyle.Bold);
    tb.ForeColor = Color.Black;
    tb.Size = new Size((int)(this.Width * 0.9), 30);
    tb.Dock = DockStyle.Left;

    panel.Controls.Add(tb);
    panel.Controls.Add(lt);
    panel.Controls.Add(l);    
    flowLayoutPanel1.Controls.Add(panel);

这是我的 Xml 代码:

<resources>
    <string name="name">Tap Crush</string>
    <string name="mode">Slow</string>
    <string name="score">12345</string>
</resources>

我没有使用 C# 解析 Xml 的先验知识。

【问题讨论】:

第 1 步。 定义一个模型类,其中包含一个 List 和每个具有 Title 和 Content 的 Resource。 步骤 2. 然后编写一些逻辑来从 xml 加载模型或将模型保存到 xml。 第 3 步。 编写一段代码来设置 UI 控件以使用数据绑定到您的模式。 步骤 4 加载数据,在 UI 中编辑并保存数据。 【参考方案1】:

定义模型类并使用数据绑定来编辑模型,然后您可以将问题分解为以下几部分:

    定义一个模型类,其中包含一个List&lt;Resource&gt;,每个Resource 都有TitleContent

    编写一些逻辑来从 xml 加载模型或将模型保存到 xml。

    编写一段代码来安排 UI 并设置 UI 控件以使用数据绑定到您的模式。

然后您可以轻松地从 xml 加载数据,在 UI 中进行编辑并将数据保存到 xml。

模型类

您可以像这样为类建模:

public class Model

    public List<Resource> Resources  get; set; 

public class Resource

    public string Title  get; set; 
    public string Content  get; set; 

设置用户界面

在表单中动态show a collection of controls 有不同的方法。在这里,我将展示如何使用 DataGridView 和 TableLayoutPanel 来做到这一点:

数据网格视图

表格布局面板

创建 DataGridView

var dg = new DataGridView();
dg.Dock = DockStyle.Fill;
dg.BorderStyle = BorderStyle.None;
dg.GridColor = Color.Black;
dg.AutoGenerateColumns = true;
dg.EditMode = DataGridViewEditMode.EditOnEnter;
dg.DataSource = model.Resources;
dg.DataBindingComplete += (o, a) =>

    dg.RowHeadersVisible = dg.ColumnHeadersVisible = false;
    dg.AllowUserToResizeColumns = false;
    dg.AllowUserToResizeRows = false;
    dg.BackgroundColor = SystemColors.Control;
    dg.Columns[0].ReadOnly = true;
    dg.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    dg.Columns[0].DefaultCellStyle.ForeColor = Color.Black;
    dg.Columns[0].DefaultCellStyle.BackColor = SystemColors.Control;
    dg.Columns[0].DefaultCellStyle.SelectionForeColor = Color.Black;
    dg.Columns[0].DefaultCellStyle.SelectionBackColor = SystemColors.Control;
    dg.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
;
this.Controls.Add(dg);

创建 TableLayoutPanel

var tlp = new TableLayoutPanel()  ColumnCount = 2, AutoSize = true ;
tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
tlp.SuspendLayout();
foreach (var resource in model.Resources)

    tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));
    var lbl = new Label()  AutoSize = true, Margin = new Padding(4) ;
    lbl.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
    lbl.DataBindings.Add(new Binding(nameof(Label.Text), resource, nameof(Resource.Title)));
    var txt = new TextBox();
    txt.DataBindings.Add(new Binding(nameof(TextBox.Text), resource, nameof(Resource.Content)));
    txt.Dock = DockStyle.Fill;
    tlp.Controls.AddRange(new Control[]  lbl, txt );

tlp.ResumeLayout();
this.Controls.Add(tlp);

加载和保存模型

你可以像这样创建一个类:

public class ModelFactory

    public Model FromXmlString(string xml)
    
        return new Model()
        
            Resources = XElement.Parse(xml).Elements()
                .Select(x => ResourceFromXElement(x)).ToList()
        ;
    
    public string ToXmlString(Model model)
    
        return new XElement("resources",
            model.Resources.Select(x => ResourceToXElement(x)).ToArray())
            .ToString();
    
    private Resource ResourceFromXElement(XElement element)
    
        return new Resource()
        
            Title = element.Attribute("name").Value,
            Content = element.Value
        ;
    
    private XElement ResourceToXElement(Resource resource)
    
        return new XElement("string",
            new XAttribute("name", resource.Title),
            resource.Content);
    

然后轻松加载和保存模型:

Model model;
ModelFactory modelFactory  = new ModelFactory();
private void loadButton_Click(object sender, EventArgs e)

    var xml = @"
    <resources>
        <string name=""name"">Tap Crush</string>
        <string name=""mode"">Slow</string>
        <string name=""score"">12345</string>
    </resources>";

    //Load model from xml
    model = modelFactory.FromXmlString(xml);

    //Setup UI
            

private void saveButton_Click(object sender, EventArgs e)

    //Save model to xml
    var xml = modelFactory.ToXmlString(model);
    MessageBox.Show(xml);
  

【讨论】:

以上是关于从 xml 加载对象,在动态 UI 中编辑值并保存回 xml的主要内容,如果未能解决你的问题,请参考以下文章

kendo ui grid 动态控制某属性

怎样从对象中获取键值并保存在对象中

Air As3 XML 编辑/保存

如何从对象类型中动态获取值并在扩展面板角材料中实现?

保存并加载动态创建的可拖动元素的位置(jQuery-UI)

Easy UI combogrid动态加载数据