So I have this code right, and it basically reads an XML file and does a few if’s to check some things and then places appropriate Controls onto the Canvas (Panel).
But it’s very long. Or, longer than I’d like it to be. And this code is like… 2 or 3 years old now.
What I want to do, is use Linq to XML.
Reading from XML File:
OpenFileDialog o = new OpenFileDialog();
o.Filter =
"wordreplaced Multimedia Format (*.mf)|*.mf|" +
"Word Document (*.docx)|*.docx|" +
"PDF Document (*.pdf)|*.pdf|" +
"Text FIle (*.txt)|*.txt";
o.Title = "wordreplaced 11 - Open Document";
using (o)
{
if (o.ShowDialog() == DialogResult.OK)
{
foreach (var controlTag in XDocument.Load(o.FileName).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.Attributes("Content").First().Value;
try
{
control.ForeColor = Color.FromArgb(
int.Parse(controlTag.Attributes("A").First().Value),
int.Parse(controlTag.Attributes("R").First().Value),
int.Parse(controlTag.Attributes("G").First().Value),
int.Parse(controlTag.Attributes("B").First().Value));
Font font = FromString(controlTag.Attributes("Font").First().Value);
control.Font = font;
}
catch { continue; }
control.BackColor = Color.Transparent;
control.MouseDown += new MouseEventHandler(control_MouseDown);
control.MouseMove += new MouseEventHandler(control_MouseMove);
control.MouseUp += new MouseEventHandler(control_MouseUp);
control.MouseClick += new MouseEventHandler(control_MouseClick);
control.MouseDoubleClick += new MouseEventHandler(control_MouseDoubleClick);
string boldness = Convert.ToString(controlTag.Attributes("Bold"));
if (boldness == "yeah")
control.Font = new Font(control.Font.Name, control.Font.Size, FontStyle.Bold);
Type t = control.GetType();
if (t.Name == "Label")
{
Label label = (Label)control;
label.AutoSize = true;
label.Location = new Point(
Convert.ToInt32(controlTag.Attributes("LocationX").First().Value),
Convert.ToInt32(controlTag.Attributes("LocationY").First().Value));
Canvas.Controls.Add(label);
// handlers.
label.MouseDown += new MouseEventHandler(label_MouseDown);
label.MouseMove += new MouseEventHandler(label_MouseMove);
label.MouseUp += new MouseEventHandler(label_MouseUp);
label.MouseClick += new MouseEventHandler(label_MouseClick);
label.MouseDoubleClick += new MouseEventHandler(label_MouseDoubleClick);
}
else if (t.Name == "LinkLabel")
{
control.Tag = controlTag.Attributes("Address").First().Value;
LinkLabel link = (LinkLabel)control;
link.AutoSize = true;
link.Location = new Point(
Convert.ToInt32(controlTag.Attributes("LocationX").First().Value),
Convert.ToInt32(controlTag.Attributes("LocationY").First().Value));
if (boldness == "yeah")
control.Font = new Font(control.Font.Name, control.Font.Size, FontStyle.Bold);
link.LinkColor = Color.White;
Canvas.Controls.Add(link);
// Add handlers.
link.MouseDown += new MouseEventHandler(link_MouseDown);
link.MouseMove += new MouseEventHandler(link_MouseMove);
link.MouseUp += new MouseEventHandler(link_MouseUp);
link.MouseClick += new MouseEventHandler(link_MouseClick);
link.MouseDoubleClick += new MouseEventHandler(link_MouseDoubleClick);
}
else if (t.Name == "PictureBox")
{
PictureBox p = (PictureBox)control;
p.Image = Base64ToImage(controlTag.Attributes("Content").First().Value);
p.AutoSize = true;
p.Location = new Point(
Convert.ToInt32(controlTag.Attributes("LocationX").First().Value),
Convert.ToInt32(controlTag.Attributes("LocationY").First().Value));
Canvas.Controls.Add(p);
// Add handlers.
p.MouseDown += new MouseEventHandler(p_MouseDown);
p.MouseMove += new MouseEventHandler(p_MouseMove);
p.MouseUp += new MouseEventHandler(p_MouseUp);
p.MouseClick += new MouseEventHandler(p_MouseClick);
p.MouseDoubleClick += new MouseEventHandler(p_MouseDoubleClick);
}
}
this.Text = "wordreplaced 11 - " + o.FileName;
}
}
Writing to XML File:
SaveFileDialog s = new SaveFileDialog();
s.Filter =
"wordReplaced Multimedia Format (*.mf)|*.mf|" +
"Word Document (*.docx)|*.docx|" +
"PDF Document (*.pdf)|*.pdf|" +
"Text FIle (*.txt)|*.txt";
s.Title = "wordReplaced 11 - Save Document";
s.CheckFileExists =
false;
XElement d;
using (s)
{
if (s.ShowDialog() == DialogResult.OK)
{
if (File.Exists(s.FileName))
d = XElement.Load(s.FileName);
else
d = new XElement("cs");
foreach (Control control in Canvas.Controls)
{
Type t = control.GetType();
switch (t.Name)
{
case "JTS.TextBox":
XElement xe0 = new XElement("JTS.TextBox",
new XAttribute("Content", control.Text),
new XAttribute("LocationX", control.Location.X),
new XAttribute("LocationY", control.Location.Y),
new XAttribute("A", control.ForeColor.A),
new XAttribute("R", control.ForeColor.R),
new XAttribute("G", control.ForeColor.G),
new XAttribute("B", control.ForeColor.B),
new XAttribute("Font", control.Font),
new XAttribute("Bold", "yeah"));
d.Add(xe0);
break;
case "LinkLabel":
LinkLabel ll = (LinkLabel)control;
try
{
XElement xe1 = new XElement("LinkLabel",
new XAttribute("Content", control.Text),
new XAttribute("LocationX", control.Location.X),
new XAttribute("LocationY", control.Location.Y),
new XAttribute("A", ll.LinkColor.A),
new XAttribute("R", ll.LinkColor.R),
new XAttribute("G", ll.LinkColor.G),
new XAttribute("B", ll.LinkColor.B),
new XAttribute("Font", ll.Font),
new XAttribute("Address", control.Tag),
new XAttribute("Bold", "yeah"));
d.Add(xe1);
}
catch
{
XElement xe1 = new XElement("LinkLabel",
new XAttribute("Content", control.Text),
new XAttribute("LocationX", control.Location.X),
new XAttribute("LocationY", control.Location.Y),
new XAttribute("A", ll.LinkColor.A),
new XAttribute("R", ll.LinkColor.R),
new XAttribute("G", ll.LinkColor.G),
new XAttribute("B", ll.LinkColor.B),
new XAttribute("Font", ll.Font),
new XAttribute("Bold", "yeah"));
d.Add(xe1);
}
break;
case "PictureBox":
PictureBox px = (PictureBox)control;
string ie = ImageToBase64(px.InitialImage, System.Drawing.Imaging.ImageFormat.Bmp);
XElement xe2 = new XElement("PictureBox",
new XAttribute("Content", ie),
new XAttribute("LocationX", px.Location.X),
new XAttribute("LocationY", px.Location.Y));
d.Add(xe2);
break;
default:
break;
}
d.Save(s.FileName);
FilePath = s.FileName;
Text = s.FileName;
ds = true;
}
}
}
Which works fine. Haven’t had a single problem with it. But it’s just such a mess to try to extend/work with etc. I am in need of a more efficient/cleaner/elegant way to write to, and read from XML files and perform linq queries against them.
I’ve read a few tutorials, and an article but I didn’t quite get it. One website mentioned a StreamWriter, which didn’t make any sense, and there seems to be many different ways to write to/read from an XML file with Linq, and it’s all very confusing to me.
Any help at all is greatly appreciated,
Thank you
I think your problem is much less using the wrong classes or tools, and much more that you need to learn how to extract methods and stop repeating code in that way.
Ideally the first code should read something like:
and that’s just to get you started; I didn’t implement several of those methods. Any time you have repeated code (e.g. the location setting code, or whatever’s going on that makes you repeat code twice inside the try/catch), you can extract that into a method.
Methods should generally be 3–5 lines long, not dozens. Break things down into small, reusable, and most importantly readable chunks that declare their intentions with clear names, so that your code reads more like your thought process and less like a long series of magical incantations that somehow make the computer do what you want it to do.