xml에서 개체를로드하고 동적 UI에서 값을 편집하고 xml에 다시 저장

Jan 12 2021

컨테이너 패널의 동적 개체, 제목 레이블, 내용 텍스트 상자를 읽고 적용했습니다. 하지만 여기에서는 텍스트 상자에 데이터를 채울 때 저장할 수 없습니다.

이것은 내 deserialize 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을 구문 분석하는 데 대한 사전 지식이 없습니다.

답변

2 RezaAghaei Jan 12 2021 at 03:11

모델 클래스를 정의하고 데이터 바인딩을 사용하여 모델을 편집 한 다음 문제를 다음 부분으로 나눌 수 있습니다.

  1. 를 포함하는 모델 클래스를 정의 List<Resource>하고 각각 Resource가지고 TitleContent.

  2. xml에서 모델을로드하거나 모델을 xml에 저장하는 로직을 작성하십시오.

  3. 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; }
}

UI 설정

양식 에 컨트롤 컬렉션 을 동적으로 표시하는 방법에는 여러 가지가 있습니다 . 여기에서는 DataGridView와 TableLayoutPanel을 사용하여이를 수행하는 방법을 보여줍니다.

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