views:

107

answers:

1

Hello,

I have an Xml file. It's format is as follows:

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

File example:

<?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>

Background: An Xml file is generated and saved on disk. When the user loads the Xml document into my application, my app will read the Xml file. And foreach control in the document, it will retrieve its properties, like so:

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

Here's what I already have:

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

... The above code generates zero errors. But, it just doesn't work. No controls are being displayed on the form. Does anybody know why the above code won't work, and how I can get it working?

All help is appreciated, thank you

Bael

+2  A: 

I would suggest you a little more generic way:

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

}

As for the color you could add an attribute to the xml file that will point to the property name of the control that we want to set and use reflection. For example:

<?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>

By the way XAML already provides much of the functionality you are trying to achieve here. Of course it assumes WPF interface which might not be your case.

Darin Dimitrov
thank you for that. I have the exact same problem. It doesn't display any controls on the form...
baeltazor
thank you :) it is working now.
baeltazor