By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
462,378 Members | 466 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 462,378 IT Pros & Developers. It's quick & easy.

How to deserialize and create a form on the fly

P: 19
Having a bit of fun here. I've read in a file in XML and deseralised it. Based on the contents of the XML file, I've generated a page on the fly (and it works).

However, the XML file contains the data for more than one page to be generated. The idea is that you click the forward button, the event is fired and the new window generated.

The deserialiser method passes the XML data to the winform generator directly which is then passed to the button click.

The problem is this. I can't get it to move to the next set of data!

Current code looks like this

Expand|Select|Wrap|Line Numbers
  1. namespace form_from_xml 
  2. {
  3.  
  4.     public class xmlhandler : Form
  5.     {
  6.         public void loaddesign()
  7.         {
  8.             FormData f;
  9.             f = null;
  10.  
  11.             try
  12.             {
  13.                 string path_env = Path.GetDirectoryName(Application.ExecutablePath) + Path.DirectorySeparatorChar;
  14.                 XmlSerializer s = new XmlSerializer(typeof(FormData));
  15.                 TextReader r = new StreamReader(path_env + "designer-test.xml");
  16.                 f = (FormData)s.Deserialize(r);
  17.                 r.Close();
  18.             }
  19.             catch (System.IO.FileNotFoundException)
  20.             {
  21.                 MessageBox.Show("Unable to find the form file", "File not found", MessageBoxButtons.OK);
  22.             }
  23.             catch (System.InvalidOperationException e)
  24.             {
  25.                 MessageBox.Show(e.ToString(), "Error", MessageBoxButtons.OK);
  26.             }
  27.             winformgen wf = new winformgen();
  28.             wf.makeform(f, 1);
  29.         }
  30.     }
  31.  
  32.     public class winformgen : Form
  33.     {
  34.         public void makeform(FormData f, int page)
  35.         {
  36.             Form form1 = new Form();
  37.             Assembly asm = typeof(Form).Assembly;
  38.             foreach (Elements fort in f.elements)
  39.             {
  40.                 System.Type tp = asm.GetType(fort.type);
  41.                 Object m = Activator.CreateInstance(tp);
  42.                 if (m is Control)
  43.                 {
  44.                     Control widget = (Control)m;
  45.                     if (fort.forwardlink != 999 || fort.backlink != 999)
  46.                     {
  47.                         Button b = new Button();
  48.                         if (fort.forwardlink != 999)
  49.                         {
  50.                             b.Name = "forward";
  51.                             b.Location = new Point(fort.winxs - 100, fort.winys - 75);
  52.                             b.Text = "Next >>";
  53.                         }
  54.                         else
  55.                         {
  56.                             b.Name = "backward";
  57.                             b.Location = new Point(fort.winxs - 200, fort.winys - 575);
  58.                             b.Text = "<< Back";
  59.                         }
  60.                         b.Height = 23;
  61.                         b.Width = 75;
  62.                         form1.Controls.Add(b);
  63.                         b.Click += delegate(object s, EventArgs e) { ButtonClick(s, e, f, fort.pagenumber); };
  64.                     }
  65.  
(nothing of any real interest happens after this point, just display the window)

The click event looks like this

Expand|Select|Wrap|Line Numbers
  1.         private void ButtonClick(object o, EventArgs e, FormData f, int page)
  2.         {
  3.             Control m = (Button)o;
  4.             if (m.Name == "forward")
  5.                 makeform(f, f.elements[page].forwardlink);
  6.             else
  7.                 makeform(f, f.elements[page].backlink);
  8.         }
  9.  
It is in the same class as the form generator. The XML reader is in a completely different class (has to be for other reasons).

There is nothing special about how the XML stuff is set up

Expand|Select|Wrap|Line Numbers
  1.     [XmlRoot("Forms")]
  2.     public class FormData
  3.     {
  4.         private ArrayList formData;
  5.  
  6.         public FormData()
  7.         {
  8.             formData = new ArrayList();
  9.         }
  10.  
  11.  
  12.         [XmlElement("Element")]
  13.         public Elements[] elements
  14.         {
  15.             get
  16.             {
  17.                 Elements[] elements = new Elements[formData.Count];
  18.                 formData.CopyTo(elements);
  19.                 return elements;
  20.             }
  21.             set
  22.             {
  23.                 if (value == null)
  24.                    return;
  25.                 Elements[] elements = (Elements[])value;
  26.                 formData.Clear();
  27.                 foreach (Elements element in elements)
  28.                     formData.Add(element);
  29.             }
  30.         }        
  31.  
  32.         public int AddItem(Elements element)
  33.         {
  34.             return formData.Add(element);
  35.         }
  36.     }
  37.  
  38.     public class Elements
  39.     {
  40.         [XmlAttribute("formname")]
  41.         public string fname;
  42.         [XmlAttribute("winxsize")]
  43.         public int winxs;
  44.  
The Elements class defines a pile of attributes and the instantates Elements with them.

int page is pretty much ignored but needs to be used but I'm not sure how to. Any help would be appreciated.

Paul
May 26 '10 #1
Share this Question
Share on Google+
14 Replies

nukefusion
Expert 100+
P: 221
@nodoid
Hi Paul,
Some of your code samples are incomplete, for example. you haven't shown the implementations of forwardlink and backlink. Although I can probably guess what they do a complete example would help.

Are you able to attach an example XML file plus the source? If so I'll look into it for you.
May 26 '10 #2

P: 19
Hi,

forward and backward call the delegate which disposes of the window and then calls the makeform method with the new page number...

Full source (the loaddesign method is called from a button click)

Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Windows.Forms;
  7. using System.IO;
  8. using System.Collections;
  9. using System.Xml;
  10. using System.Xml.Serialization;
  11. using System.Reflection;
  12.  
  13. namespace form_from_xml 
  14. {
  15.  
  16.     public class xmlhandler : Form
  17.     {
  18.         public void loaddesign(int m)
  19.         {
  20.             FormData f;
  21.             f = null;
  22.  
  23.             try
  24.             {
  25.                 string path_env = Path.GetDirectoryName(Application.ExecutablePath) + Path.DirectorySeparatorChar;
  26.                 XmlSerializer s = new XmlSerializer(typeof(FormData));
  27.                 TextReader r = new StreamReader(path_env + "designer-test.xml");
  28.                 f = (FormData)s.Deserialize(r);
  29.                 r.Close();
  30.             }
  31.             catch (System.IO.FileNotFoundException)
  32.             {
  33.                 MessageBox.Show("Unable to find the form file", "File not found", MessageBoxButtons.OK);
  34.             }
  35.             catch (System.InvalidOperationException e)
  36.             {
  37.                 MessageBox.Show(e.ToString(), "Error", MessageBoxButtons.OK);
  38.             }
  39.             winformgen wf = new winformgen();
  40.             wf.makeform(f, 1);
  41.         }
  42.     }
  43.  
  44.     public class winformgen : Form
  45.     {
  46.         public void makeform(FormData f, int page)
  47.         {
  48.             Form form1 = new Form();
  49.             Assembly asm = typeof(Form).Assembly;
  50.             foreach (Elements fort in f.elements)
  51.             {
  52.                 System.Type tp = asm.GetType(fort.type);
  53.                 Object m = Activator.CreateInstance(tp);
  54.                 if (m is Control)
  55.                 {
  56.                     Control widget = (Control)m;
  57.                     if (fort.forwardlink != 999 || fort.backlink != 999)
  58.                     {
  59.                         Button b = new Button();
  60.                         if (fort.forwardlink != 999)
  61.                         {
  62.                             b.Name = "forward";
  63.                             b.Location = new Point(fort.winxs - 100, fort.winys - 75);
  64.                             b.Text = "Next >>";
  65.                         }
  66.                         else
  67.                         {
  68.                             b.Name = "backward";
  69.                             b.Location = new Point(fort.winxs - 200, fort.winys - 575);
  70.                             b.Text = "<< Back";
  71.                         }
  72.                         b.Height = 23;
  73.                         b.Width = 75;
  74.                         form1.Controls.Add(b);
  75.                         b.Click += delegate(object s, EventArgs e) { ButtonClick(s, e, f, fort.pagenumber, form1); };
  76.  
  77.                     }
  78.                     if (fort.type != "System.Windows.Forms.PictureBox" && fort.type != "System.Windows.Forms.RichTextBox")
  79.                     {
  80.                         widget.Text = fort.text;
  81.                         widget.Location = new Point(fort.xpos, fort.ypos);
  82.                         widget.Height = fort.ysize;
  83.                         widget.Width = fort.xsize;
  84.                         widget.Name = fort.name;
  85.                         form1.Controls.Add(widget);
  86.                     }
  87.                     if (fort.ev == true)
  88.                     {
  89.                         widget.Click += new System.EventHandler(this.widget_Click);
  90.                     }
  91.                     if (fort.type == "System.Windows.Forms.PictureBox" && fort.external == false && fort.externalplace != "")
  92.                     {
  93.                         PictureBox b = new PictureBox();
  94.                         b.Location = new Point(fort.xpos, fort.ypos);
  95.                         b.Name = fort.name;
  96.                         b.Height = fort.ysize;
  97.                         b.Width = fort.xsize;
  98.                         b.SizeMode = PictureBoxSizeMode.StretchImage;
  99.                         b.Image = Image.FromFile(fort.externalplace);
  100.                         form1.Controls.Add(b);
  101.                     }
  102.                     if (fort.type == "System.Windows.Forms.RichTextBox" && fort.external == false && fort.externalplace != "")
  103.                     {
  104.                         RichTextBox b = new RichTextBox();
  105.                         b.Location = new Point(fort.xpos, fort.ypos);
  106.                         b.Name = fort.name;
  107.                         b.Height = fort.ysize;
  108.                         b.Width = fort.xsize;
  109.                         b.ReadOnly = true;
  110.                         b.LoadFile(fort.externalplace);
  111.                         form1.Controls.Add(b);
  112.                     }       
  113.                 }
  114.             }
  115.             form1.FormBorderStyle = FormBorderStyle.FixedDialog;
  116.             form1.MaximizeBox = false;
  117.             form1.MinimizeBox = false;
  118.             form1.StartPosition = FormStartPosition.CenterScreen;
  119.             form1.Width = f.elements[page].winxs;
  120.             form1.Height = f.elements[page].winys;
  121.             form1.Text = f.elements[page].title;
  122.             form1.Show();
  123.         }
  124.  
  125.         private void widget_Click(object o, EventArgs e)
  126.         {
  127.             MessageBox.Show("Hello", "Hello", MessageBoxButtons.OK);
  128.         }
  129.  
  130.         private void ButtonClick(object o, EventArgs e, FormData f, int page, Form f1)
  131.         {
  132.             Control m = (Button)o;
  133.             if (m.Name == "forward")
  134.             {
  135.                 f1.Dispose();
  136.                 makeform(f, f.elements[page - 1].forwardlink);
  137.             }
  138.             else
  139.             {
  140.                 f1.Dispose();
  141.                 makeform(f, f.elements[page - 1].backlink);
  142.             }
  143.         }
  144.     }
  145.  
  146.     [XmlRoot("Forms")]
  147.     public class FormData
  148.     {
  149.         private ArrayList formData;
  150.  
  151.         public FormData()
  152.         {
  153.             formData = new ArrayList();
  154.         }
  155.  
  156.  
  157.         [XmlElement("Element")]
  158.         public Elements[] elements
  159.         {
  160.             get
  161.             {
  162.                 Elements[] elements = new Elements[formData.Count];
  163.                 formData.CopyTo(elements);
  164.                 return elements;
  165.             }
  166.             set
  167.             {
  168.                 if (value == null)
  169.                    return;
  170.                 Elements[] elements = (Elements[])value;
  171.                 formData.Clear();
  172.                 foreach (Elements element in elements)
  173.                     formData.Add(element);
  174.             }
  175.         }        
  176.  
  177.         public int AddItem(Elements element)
  178.         {
  179.             return formData.Add(element);
  180.         }
  181.     }
  182.  
  183.     public class Elements
  184.     {
  185.         [XmlAttribute("formname")]
  186.         public string fname;
  187.         [XmlAttribute("winxsize")]
  188.         public int winxs;
  189.         [XmlAttribute("winysize")]
  190.         public int winys;
  191.         [XmlAttribute("wintitle")]
  192.         public string title;
  193.         [XmlAttribute("type")]
  194.         public string type;
  195.         [XmlAttribute("xpos")]
  196.         public int xpos;
  197.         [XmlAttribute("ypos")]
  198.         public int ypos;
  199.         [XmlAttribute("xsize")]
  200.         public int xsize;
  201.         [XmlAttribute("ysize")]
  202.         public int ysize;
  203.         [XmlAttribute("name")]
  204.         public string name;
  205.         [XmlAttribute("externaldata")]
  206.         public bool external;
  207.         [XmlAttribute("externalplace")]
  208.         public string externalplace;
  209.         [XmlAttribute("text")]
  210.         public string text;
  211.         [XmlAttribute("questions")]
  212.         public bool questions;
  213.         [XmlAttribute("questiontype")]
  214.         public string qtype;
  215.         [XmlAttribute("numberqs")]
  216.         public int numberqs;
  217.         [XmlAttribute("answerfile")]
  218.         public string ansfile;
  219.         [XmlAttribute("hasevent")]
  220.         public bool ev;
  221.         [XmlAttribute("backlink")]
  222.         public int backlink;
  223.         [XmlAttribute("forwardlink")]
  224.         public int forwardlink;
  225.         [XmlAttribute("pagenumber")]
  226.         public int pagenumber;
  227.  
  228.         public Elements()
  229.         {
  230.         }
  231.  
  232.         public Elements(string fn, int wx, int wy, string wt, string t, int x, int y, int xs, int ys, string n, bool ext, 
  233.             string extpl, string te, bool q, string qt, int num, string ans, bool eve, int back, int end, int now)
  234.         {
  235.             fname = fn;
  236.             winxs = wx;
  237.             winys = wy;
  238.             title = wt;
  239.             type = t;
  240.             xpos = x;
  241.             ypos = y;
  242.             xsize = xs;
  243.             ysize = ys;
  244.             name = n;
  245.             external = ext;
  246.             externalplace = extpl;
  247.             text = te;
  248.             questions = q;
  249.             qtype = qt;
  250.             numberqs = num;
  251.             ansfile = ans;
  252.             backlink = back;
  253.             ev = eve;
  254.             forwardlink = end;
  255.             pagenumber = now;
  256.         }
  257.     }
  258. }
  259.  
XML file

Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Forms>
  3.     <Element formname="Test Window" winxsize="800" winysize="350" wintitle = "The eye" 
  4.         type="System.Windows.Forms.PictureBox" xpos="25" ypos="50" xsize="300" ysize="200" name="pb1"
  5.         externaldata="false" externalplace="h:\eye.jpg" text="" questions="true" questiontype="none"
  6.         numberqs="0" answerfile="none" hasevent="false" backlink="999" forwardlink="999" 
  7.         pagenumber="1" />
  8.     <Element formname="Test Window" winxsize="800" winysize="350" wintitle = "The eye" 
  9.         type="System.Windows.Forms.RichTextBox" xpos="350" ypos="50" xsize="400" ysize="200" name="rt1"
  10.         externaldata="false" externalplace="h:\theeye.rtf" text="" questions="true" questiontype="none"
  11.         numberqs="0" answerfile="none" hasevent="false" backlink="999" forwardlink="2" 
  12.         pagenumber="1" />
  13.     <Element formname="Test Window" winxsize="800" winysize="350" wintitle = "The eye" 
  14.         type="System.Windows.Forms.PictureBox" xpos="25" ypos="50" xsize="300" ysize="200" name="pb1"
  15.         externaldata="false" externalplace="h:\eye.jpg" text="" questions="true" questiontype="none"
  16.         numberqs="0" answerfile="none" hasevent="false" backlink="999" forwardlink="999" 
  17.         pagenumber="2" />    
  18.     <Element formname="Test Window" winxsize="800" winysize="350" wintitle = "The eye" 
  19.         type="System.Windows.Forms.RichTextBox" xpos="350" ypos="50" xsize="400" ysize="200" name="rt1"
  20.         externaldata="false" externalplace="h:\theeye-lang.rtf" text="" questions="true" questiontype="none"
  21.         numberqs="0" answerfile="none" hasevent="false" backlink="1" forwardlink="999" 
  22.         pagenumber="2" />
  23. </Forms>
  24.  
Thanks

Paul
May 26 '10 #3

P: 19
One solution may be just to read in the data where pagenumber == page, but that would be slightly messy

Something like

XmlDocument doc = new XmlDocument();
doc.Load(path_env + "designer-test.xml");
f = doc.XmlSingleNode("pagenumber");

though that would probably not really work as it would only read one set of data not multiple sets....

Hmmm.....
May 26 '10 #4

nukefusion
Expert 100+
P: 221
Hi Paul,

I've had a look at your code. Is the MakeForm method supposed to just read in the form data at the index specified by the page parameter? Because at the moment your doing a foreach loop over each element in the XML data and creating all the controls for each element, but adding them all to one form instance (form1).

Expand|Select|Wrap|Line Numbers
  1.  public void makeform(FormData f, int page)
  2.  {
  3.         Form form1 = new Form();
  4.         Assembly asm = typeof(Form).Assembly;
  5.         foreach (Elements fort in f.elements)
  6.         {
  7.             .... more code here adding controls.....
  8.  
  9.         }
  10.         form1.Show();
  11.  
  12.  }
  13.  
If the intention is to create one form at a time then remove the foreach loop and replace with:

Expand|Select|Wrap|Line Numbers
  1. Elements fort = f.elements[page];
  2.  
Does that make sense?
May 26 '10 #5

P: 19
It does :-)

However trying that only gives one thing in the window (in the first case, it's the text box). The XML has multiple objects on a form, but only the last is shown.

I'm now thinking of setting up a simple for loop which counts how many objects there are with pagenumber == page and loop it through that way but again, that would cause another layer of problems unless I add another XML field with an object number counter on it...

Hmmmmmm.....
May 26 '10 #6

nukefusion
Expert 100+
P: 221
Hi Paul,
Ok, I've had a closer look at the XML and I see what you mean. If you want to de-serialize a single form with multiple elements then I think the issue is probably your XML structure. Currently it's unclear whether the Element node represents a Form, or a Control; it has attributes for both.

Maybe a structure like the following would work better?

Expand|Select|Wrap|Line Numbers
  1. <Forms>
  2.     <Form name="Test Window" width="800" height="350">
  3.         <Element type="System.Windows.Forms.PictureBox" xpos="25" ypos="25" />
  4.         <Element type="System.Windows.Forms.TextBox" xpos="125" ypos="250" />        
  5.     </Form>
  6.     <Form name="Test Window 2" width="800" height="350">
  7.         <Element type="System.Windows.Forms.PictureBox" xpos="25" ypos="25" />
  8.         <Element type="System.Windows.Forms.TextBox" xpos="125" ypos="250" />        
  9.     </Form>
  10. </Forms>
  11.  
That's just a basic outline. You can add your other attributes in, adding any attributes that relate purely to the form to the Form node and anything that relates to the control only on the Element node.
May 26 '10 #7

P: 19
It would probably make life simpler to do that, after all, get the XML deserialize bit correct and the rest should work.

For your suggestion though, would the Elements class need to be re-written or is it enough just to restructure the XML?
May 26 '10 #8

nukefusion
Expert 100+
P: 221
@nodoid
No, you'd need to adjust the Elements class too. I think I'd recreate the XML to map more closely what we are trying to store - a list of forms each with it's own list of elements.

I'd probably have one class for the Forms collection, let's call it FormsList to avoid confusion (there's already a FormsCollection class in the WinForms namespace)

Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Xml.Serialization;
  5.  
  6. namespace WindowsFormsApplication3
  7. {
  8.     /// <summary>
  9.     /// A serializable collection of forms.
  10.     /// </summary>
  11.     [Serializable]
  12.     [XmlRoot("Forms")]
  13.     public class FormList
  14.     {
  15.         private IList<FormData> forms;
  16.  
  17.         /// <summary>
  18.         /// Initializes a new instance of the <see cref="Forms"/> class.
  19.         /// </summary>
  20.         public FormList()
  21.         {
  22.             forms = new List<FormData>();
  23.         }
  24.  
  25.         [XmlElement("Form")]
  26.         public FormData[] Forms
  27.         {
  28.             get { return this.forms.ToArray(); }
  29.             set { this.forms = new List<FormData>(value); }
  30.         }
  31.     }
  32. }
  33.  
Then a FormData class to represent the data from one form:

Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Xml.Serialization;
  5.  
  6. namespace WindowsFormsApplication3
  7. {
  8.     /// <summary>
  9.     /// Represents a single form and the elements within it.
  10.     /// </summary>
  11.     [Serializable]
  12.     public class FormData
  13.     {
  14.         private IList<Element> elements;
  15.  
  16.         /// <summary>
  17.         /// Initializes a new instance of the <see cref="FormData"/> class.
  18.         /// </summary>
  19.         public FormData()
  20.         {
  21.             elements = new List<Element>();
  22.         }
  23.  
  24.         public string Name { get; set; }
  25.  
  26.         public int Width { get; set; }
  27.  
  28.         public int Height { get; set; }
  29.  
  30.         public string Title { get; set; }
  31.  
  32.         public int BackLink { get; set; }
  33.  
  34.         public int ForwardLink { get; set; }
  35.  
  36.         [XmlElement("Element")]
  37.         public Element[] Elements
  38.         {
  39.             get { return this.elements.ToArray(); }
  40.             set { this.elements = new List<Element>(value); }
  41.         }
  42.     }
  43. }
  44.  
Then a revised Element class:

Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Xml.Serialization;
  3.  
  4. namespace WindowsFormsApplication3
  5. {
  6.     /// <summary>
  7.     /// Represents an element within a form.
  8.     /// </summary>
  9.     [Serializable]
  10.     public class Element
  11.     {
  12.         [XmlAttribute("Name")]
  13.         public string ElementName { get; set; }
  14.  
  15.         public int X { get; set; }
  16.  
  17.         public int Y { get; set; }
  18.  
  19.         public int Width { get; set; }
  20.  
  21.         public int Height { get; set; }
  22.  
  23.         public string Title { get; set; }
  24.  
  25.         public string Text { get; set; }
  26.  
  27.         [XmlAttribute("Type")]
  28.         public string ElementType { get; set; }
  29.  
  30.         /// <summary>
  31.         /// Initializes a new instance of the <see cref="Element"/> class.
  32.         /// </summary>
  33.         public Element()
  34.         {
  35.         }      
  36.     }
  37. }
  38.  
This would then serialize/deserialize an XML file like this:

Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <Forms>
  3.   <Form Name="Test Window" Width="800" Height="350" Title="The eye 1" BackLink="" ForwardLink="2">
  4.     <Element Name="pb1" Type="System.Windows.Forms.PictureBox" X="25" Y="50" Width="300" Height="200" Text=""></Element>
  5.   </Form>
  6.   <Form Name="Test Window" Width="800" Height="350" Title="The eye 2" BackLink="" ForwardLink="2">
  7.     <Element Name="rt1" Type="System.Windows.Forms.RichTextBox" X="350" Y="50" Width="400" Height="200" Text=""></Element>
  8.   </Form>
  9.   <Form Name="Test Window" Width="800" Height="350" Title="The eye 1" BackLink="" ForwardLink="2">
  10.     <Element Name="pb1" Type="System.Windows.Forms.PictureBox" X="25" Y="50" Width="300" Height="200" Text=""></Element>
  11.   </Form>
  12.   <Form Name="Test Window" Width="800" Height="350" Title="The eye 2" BackLink="" ForwardLink="2">
  13.     <Element Name="rt1" Type="System.Windows.Forms.RichTextBox" X="350" Y="50" Width="400" Height="200" Text=""></Element>
  14.   </Form>
  15. </Forms>
  16.  
I think that probably represents the data you're trying to store better and using that format you should be able to solve your problem.
May 27 '10 #9

P: 19
Okay, no idea on this one. I've sorted a few other problems out, but the following is seriously annoying me as I can't see any valid reason for the error occuring...

Expand|Select|Wrap|Line Numbers
  1.     [Serializable]
  2.     public class FormData
  3.     {
  4.         public List<Element> elements;
  5.         public FormData()
  6.         {
  7.             elements = new List<Element>();
  8.         }
  9.  
  10.         public string Name { get; set; }
  11.         public int Width { get; set; }
  12.         public int Height { get; set; }
  13.         public string Title { get; set; }
  14.         public int BackLink { get; set; }
  15.         public int ForwardLink { get; set; }
  16.         public int PageNumber { get; set; }
  17.  
  18.         [XmlElement("Element")]
  19.         public Element[] Elements
  20.         {
  21.             get { return this.elements.ToArray(); }
  22.             set { this.elements = new List<Element>(value); }
  23.         }
  24.     }
  25.  
  26.     [Serializable]
  27.     public class Element
  28.     {
  29.         [XmlAttribute("Name")]
  30.         public string ElementName { get; set; }
  31.         public int X { get; set; }
  32.         public int Y { get; set; }
  33.         public int Width { get; set; }
  34.         public int Height { get; set; }
  35.         public string Title { get; set; }
  36.         public string Text { get; set; }
  37.  
  38.         [XmlAttribute("Type")]
  39.         public string ElementType { get; set; }
  40.  
  41.         [XmlAttribute("External")]
  42.         public bool WithExternal { get; set; }
  43.         public string ExternalFile { get; set; }
  44.  
  45.         [XmlAttribute("Events")]
  46.         public bool HasClick { get; set; }
  47.         public bool HasWritable { get; set; }
  48.         public bool HasNumeric { get; set; }
  49.  
  50.         public Element()
  51.         {
  52.         }      
  53.     }
  54.  
Expand|Select|Wrap|Line Numbers
  1. public List<Element> elements;
and
Expand|Select|Wrap|Line Numbers
  1. public Element[] Elements
are complaining that the type Element can't be found (am I missing a using directive).

Oh for the days of simple errors and other such things....
May 28 '10 #10

P: 19
Bloody visual studio 2008 - false positives... move along, nothing to see here...
May 28 '10 #11

P: 19
Okay, after a chunk of time on this I've come across two problems

1. The deserializer.

Currently it's using FormData to read in which gives an error as the first thing sucked in from the XML file is FormList. Okay, not a biggy, alter the references for FormData to FormList.

Ah. Problem. The foreach is annoyed at foreach (Element fort in f.Forms[].elements) - it's expecting a value in the brackets by the looks of it.

2. The XML format

Current code looks like this for the Elements class

Expand|Select|Wrap|Line Numbers
  1.    [Serializable]
  2.     public class Element
  3.     {
  4.         [XmlAttribute("Name")]
  5.         public string ElementName { get; set; }
  6.         public int X { get; set; }
  7.         public int Y { get; set; }
  8.         public int Width { get; set; }
  9.         public int Height { get; set; }
  10.         public string Title { get; set; }
  11.         public string Text { get; set; }
  12.  
  13.         [XmlAttribute("Type")]
  14.         public string ElementType { get; set; }
  15.  
  16.         [XmlAttribute("External")]
  17.         public bool WithExternal { get; set; }
  18.         public string ExternalFile { get; set; }
  19.  
  20.         [XmlAttribute("Events")]
  21.         public bool HasClick { get; set; }
  22.         public bool HasWritable { get; set; }
  23.         public bool HasNumeric { get; set; }
  24.         public bool HasRO { get; set; }
  25.  
  26.         public Element()
  27.         {
  28.         }      
  29.     }
  30. }
  31.  
(I've added a few bits)

AIUI this would make the format of the XML like this

Expand|Select|Wrap|Line Numbers
  1. <forms>
  2. <form // form definition />
  3. <element>
  4. <Name elementname="foo" // etc>
  5. <Type elementtype="foo" />
  6. <External // links to the outside world />
  7. <HasEvents // event triggers />
  8. </element>
  9. // whatever is next in form
  10. </form>
  11. </forms>
  12.  
Am I correct in thinking this or is my understanding still sketchy?
Jun 1 '10 #12

nukefusion
Expert 100+
P: 221
The properties in the Elements class that have been decorated with the XmlAttribute metadata will be realised as attributes in the XML file. So it will look more like this:

Expand|Select|Wrap|Line Numbers
  1. <Element Name="" Type="" External="">
  2. </Element>
  3.  
Jun 1 '10 #13

P: 19
Ah. Okay, that makes some sense. What happens though with the bits declared within the attribute? Would it become

Expand|Select|Wrap|Line Numbers
  1. <Element Name="foo" ElementName="bar" X="100" Y="150" ...
  2.  
followed by the other bits declared in Name then something similar for the other attributes or do I need to declare them some other way?
Jun 1 '10 #14

nukefusion
Expert 100+
P: 221
The XmlAttribute only applies to the property it's immediately above; they're not grouped. By default, the properties will export as Nodes. With that class definition, what you'll get will be more like:

Expand|Select|Wrap|Line Numbers
  1. <Element Name="" Type="" External="" Events="">
  2.     <X></X>
  3.     <Y></Y>
  4.     <Width></Width>
  5.     <Height></Height>
  6.     <Title></Title>
  7.     <Text></Text>
  8.     <ExternalFile></ExternalFile>
  9.     <HasWritable></HasWritable>
  10.     <HasNumeric></HasNumeric>
  11.     <HasRO></HasRO>
  12. </Element>
  13.  
Jun 1 '10 #15

Post your reply

Sign in to post your reply or Sign up for a free account.