更优雅/高效的方式吗? (XML / Linq / Read& Write)

时间:2011-05-16 05:12:02

标签: c# .net xml winforms linq

所以我有正确的代码,它基本上读取一个XML文件并做一些检查,然后将适当的控件放到Canvas(Panel)上。

但它很长。或者,比我想要的还要长。这段代码现在就像...... 2或3岁。

我想要做的是将Linq用于XML。

从XML文件中读取:

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

写入XML文件:

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

哪个工作正常。没有一个问题。但是尝试扩展/使用等等就是一团糟。我需要一种更高效/更清晰/更优雅的方式来编写,读取XML文件并对它们执行linq查询。

我已经阅读了一些教程和一篇文章,但我并没有完全理解它。一个网站提到了一个没有任何意义的StreamWriter,并且似乎有很多不同的方法可以用Linq写入/读取XML文件,这对我来说非常困惑。

非常感谢任何帮助,

谢谢

2 个答案:

答案 0 :(得分:4)

我认为使用错误的类或工具可以解决问题,更需要学习如何提取方法并停止以这种方式重复代码。

理想情况下,第一个代码应该是:

// In whatever method loads the file
string fileName = GetFileNameFromUser();
if (fileName != null)
{
    var rootElement = GetRootElementOfXmlFile(fileName);
    foreach (var controlTag in rootElement)
    {
        ProcessControlTag(controlTag);
    }
}

private static void ProcessControlTag(XElement controlTag)
{
    var type = GetControlType(controlTag);
    if (type == null)
    {
        return;
    }

    var control = CreateControl(controlType, controlTag);
    Canvas.Controls.Add(control);
}

private static void CreateControl(Type controlType, XElement controlTag)
{
    var control = (Control)Activator.CreateInstance(controlType);
    AddCommonControlModifications(control, controlTag);

    if (controlType.Name == "Label")
    {
        AddLabelModifications(control, controlTag);
    }
    else if (controlType.Name == "LinkLabel")
    {
        AddLinkLabelModifications(control, controlTag);
    }
    else if (controlType.Name == "PictureBox")
    {
        AddPictureBoxModifications(control, controlTag);
    }
}

这只是为了让你开始;我没有实现其中的几种方法。任何时候你重复代码(例如位置设置代码,或任何正在进行的代码都会使你在try / catch中重复代码两次),你可以将它提取到一个方法中。

方法通常应该是3-5行,而不是几十行。将事情分解为小的,可重复使用的,最重要的可读块,用明确的名称声明他们的意图,这样你的代码就会更像你的思维过程而不像一长串神奇的咒语计算机做你想做的事。

答案 1 :(得分:2)

代码有效吗?您有任何新的要求要实施吗?你没有更重要的事情要做吗?

如果没有损坏,请不要修理它。你只是要介绍bug。