Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
116 views
in Technique[技术] by (71.8m points)

c# - Load object from xml, edit values in a dynamic UI and save back to xml

I just read and applied it to the dynamic object on the panel for the container, the label for the title, the textbox for the contents. but here I can't save it when I fill in the data in the textbox.

this is my deserialize xml code:

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

and this my Xml Code:

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

I have no prior knowledge of parsing Xml with C#.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Define model classes and use databinding to edit the model, then you can break the problem to the following pieces:

  1. Defining a Model class containing a List<Resource> and each Resource having Title and Content.

  2. Write some logic to load model from xml or save model to xml.

  3. Write a piece of code to arrange UI and setup UI controls to use databinding to your mode.

Then you can easily Load data from xml, edit in the UI and Save data to xml.

Model classes

You can model classes like this:

public class Model
{
    public List<Resource> Resources { get; set; }
}
public class Resource
{
    public string Title { get; set; }
    public string Content { get; set; }
}

Setting up UI

There are different approaches to dynamically show a collection of controls in a form. Here I'll show how you can do that using a DataGridView as well as a TableLayoutPanel:

DataGridView

enter image description here

TableLayoutPanel

enter image description here

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

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

Load and Save Model

You can create a class like this:

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

Then easily load and save model:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...