Чтение и обработка XML-файла - PullRequest
4 голосов
/ 07 февраля 2010

У меня есть XML-файл. Он имеет следующий формат:

ControlType > Content > LocationX > LocationY > ForeColor/LinkColor > Int > Int > Int > Int

Пример файла:

<?xml version="1.0" encoding="utf-8"?>
<cs>
  <Label Content="Double-click to edit." LocationX="583" LocationY="254" A="255" R="255" G="255" B="255" />
  <LinkLabel Content="Double-click to edit." LocationX="613" LocationY="251" A="255" R="0" G="0" B="0" />
</cs>

Фон: XML-файл создается и сохраняется на диске. Когда пользователь загружает документ Xml в мое приложение, мое приложение будет читать файл Xml. И каждый элемент управления в документе будет извлекать свои свойства, например:

foreach(Control control in XmlFile)
{
     // get control type
     // get control content
     // get LocationX
     // get LocationY
     // get Color
     // get Int
     // get Int
     // get Int
     // get Int

     // Do something with retrieved data.
}

Вот что у меня уже есть:

OpenFileDialog o = new OpenFileDialog();

o.Filter =
    "T Multimedia Format (*.mf)|*.mf|" +
    "Word Document (*.docx)|*.docx|" +
    "PDF Document (*.pdf)|*.pdf|" +
    "Text FIle (*.txt)|*.txt";
o.Title = "T 11 - Open Document";

using (o)
{
    if (o.ShowDialog() == DialogResult.OK)
    {
        XDocument xdc = XDocument.Load(o.FileName);

        var cs = xdc.Elements("cs");
        foreach (var im in cs)
        {
            if (im.Name == "Label")
            {
                Label label = new Label();
                label.MouseClick += new MouseEventHandler(label_MouseClick);
                label.MouseDown += new MouseEventHandler(label_MouseDown);
                label.MouseMove += new MouseEventHandler(label_MouseMove);
                label.MouseUp += new MouseEventHandler(label_MouseUp);
                label.MouseDoubleClick += new MouseEventHandler(label_MouseDoubleClick);

                label.Text = im.Attribute("Content").Value;

                label.Location = new Point(
                    Convert.ToInt32(im.Attribute("LocationX").Value),
                    Convert.ToInt32(im.Attribute("LocationY").Value));

                label.BackColor = Color.Transparent;
                label.ForeColor = Color.FromArgb(
                    Convert.ToInt32(im.Attribute("A").Value),
                    Convert.ToInt32(im.Attribute("R").Value),
                    Convert.ToInt32(im.Attribute("G").Value),
                    Convert.ToInt32(im.Attribute("B").Value));

                label.AutoSize = true;
                Canvas.Controls.Add(label);

                label.BringToFront();
            }
            else if (im.Name == "LinkLabel")
            {
                LinkLabel link = new LinkLabel();
                link.MouseClick += new MouseEventHandler(link_MouseClick);
                link.MouseDown += new MouseEventHandler(link_MouseDown);
                link.MouseMove += new MouseEventHandler(link_MouseMove);
                link.MouseUp += new MouseEventHandler(link_MouseUp);
                link.MouseDoubleClick += new MouseEventHandler(link_MouseDoubleClick);

                link.Text = im.Attribute("Content").Value;

                link.Location = new Point(
                    Convert.ToInt32(im.Attribute("LocationX").Value),
                    Convert.ToInt32(im.Attribute("LocationY").Value));

                link.BackColor = Color.Transparent;
                link.LinkColor = Color.FromArgb(
                    Convert.ToInt32(im.Attribute("A").Value),
                    Convert.ToInt32(im.Attribute("R").Value),
                    Convert.ToInt32(im.Attribute("G").Value),
                    Convert.ToInt32(im.Attribute("B").Value));

                link.AutoSize = true;
                Canvas.Controls.Add(link);

                link.BringToFront();
            }
        }
    }
}

... Приведенный выше код генерирует ноль ошибок. Но это просто не работает. В форме не отображаются элементы управления. Кто-нибудь знает, почему приведенный выше код не будет работать, и как я могу заставить его работать?

Вся помощь приветствуется, спасибо

Bael

1 Ответ

3 голосов
/ 07 февраля 2010

Я бы предложил вам немного более общий способ:

private void Form1_Load(object sender, EventArgs e)
{
    foreach (var controlTag in XDocument.Load("settings.xml").Root.Elements())
    {
        var controlType = Type.GetType(string.Format("System.Windows.Forms.{0}, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", controlTag.Name.LocalName), false);
        if (controlType == null || !typeof(Control).IsAssignableFrom(controlType))
        {
            continue;
        }
        var control = (Control)Activator.CreateInstance(controlType);
        control.Text = controlTag.Attribute("Content").Value;
        control.Location = new Point(
            int.Parse(controlTag.Attribute("LocationX").Value),
            int.Parse(controlTag.Attribute("LocationY").Value)
        );
        control.BackColor = Color.Transparent;

        control.MouseClick += mouseClick;
        control.MouseDown += mouseDown;
        control.MouseMove += mouseMove;
        control.MouseUp += mouseUp;
        control.MouseDoubleClick += mouseDoubleClick;

        Controls.Add(control);
    }

}

Что касается цвета, вы можете добавить в xml-файл атрибут, который будет указывать на имя свойства элемента управления, который мы хотим установить и использовать отражение. Например:

<?xml version="1.0" encoding="utf-8"?>
<cs>
  <Label Content="Double-click to edit." LocationX="583" LocationY="254" A="255" R="255" G="255" B="255" ColorProperty="ForeColor" />
  <LinkLabel Content="Double-click to edit." LocationX="613" LocationY="251" A="255" R="0" G="0" B="0" ColorProperty="LinkColor" />
</cs>

Кстати, XAML уже предоставляет большую часть функциональности, которую вы пытаетесь достичь здесь. Конечно, он предполагает интерфейс WPF, который может не соответствовать вашему случаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...