更优雅/更有效的方式来做到这一点? (XML/Linq/读和写)

发布于 2024-11-07 14:13:36 字数 11578 浏览 0 评论 0原文

所以我的代码是正确的,它基本上读取一个 XML 文件并执行一些 if 来检查某些内容,然后将适当的控件放置到画布(面板)上。

但它很长。或者,比我希望的时间还要长。这段代码已经有两三年了。

我想做的是使用 Linq to 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 文件似乎有很多不同的方法,这让我非常困惑。

非常感谢任何帮助,

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

萌吟 2024-11-14 14:13:36

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

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

// 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 行,而不是数十行。将事物分解成小的、可重用的、最重要的可读块,用清晰的名称声明它们的意图,这样你的代码读起来更像你的思维过程,而不是像一长串神奇的咒语,不知何故,计算机做你想让它做的事。

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:

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

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.

暗喜 2024-11-14 14:13:36

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

如果它没有坏,就不要修理它。你只会引入错误。

Code works? Do you have any new requirements to implement? Do you have nothing more important to do?

If it ain't broke, don't fix it. You're just going to introduce bugs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文