Cargue el objeto desde xml, edite los valores en una interfaz de usuario dinámica y guárdelo de nuevo en xml

Jan 12 2021

Lo leí y lo apliqué al objeto dinámico en el panel del contenedor, la etiqueta del título, el cuadro de texto del contenido. pero aquí no puedo guardarlo cuando completo los datos en el cuadro de texto.

este es mi código xml deserializar:

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

y este mi código XML:

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

No tengo conocimientos previos sobre el análisis de XML con C #.

Respuestas

2 RezaAghaei Jan 12 2021 at 03:11

Defina clases de modelo y use el enlace de datos para editar el modelo, luego puede dividir el problema en las siguientes partes:

  1. Definición de una clase de modelo que contiene un List<Resource>y cada uno Resourcecon Titley Content.

  2. Escriba algo de lógica para cargar el modelo desde xml o guarde el modelo en xml.

  3. Escriba un fragmento de código para organizar la interfaz de usuario y configurar los controles de la interfaz de usuario para usar el enlace de datos a su modo.

Luego, puede cargar datos fácilmente desde xml, editar en la interfaz de usuario y guardar datos en xml.

Clases modelo

Puede modelar clases como esta:

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

Configurar la interfaz de usuario

Existen diferentes enfoques para mostrar dinámicamente una colección de controles en un formulario. Aquí mostraré cómo puede hacer eso usando un DataGridView así como un TableLayoutPanel:

DataGridView

TableLayoutPanel

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

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

Cargar y guardar modelo

Puedes crear una clase como esta:

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

Luego cargue y guarde fácilmente el modelo:

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