2011-05-16 58 views
0

所以我有這個代碼的權利,它基本上讀取一個XML文件,並做了一些如果檢查一些事情,然後將適當的控件放置在畫布(面板)上。這樣做更優雅/有效嗎? (XML/Linq /讀寫)

但它很長。或者,比我想要的要長。而這個代碼就像......現在2或3歲。

我想要做的是使用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文件,並從XML文件中讀取數據並對它們執行linq查詢。

我讀過一些教程和一篇文章,但我並沒有完全理解它。一個網站提到了一個StreamWriter,它沒有任何意義,似乎有很多不同的方式來用Linq寫入/讀取XML文件,這對我來說都非常混亂。

在所有的任何幫助是極大的讚賞,

謝謝

+0

你不是已經在使用LINQ to XML嗎? XDocument在System.Xml中。 ** Linq **程序集。 – alex 2011-05-16 05:18:42

+0

是的,但它與我見過的其他一切完全不同。這是如此龐大/醜陋/長 – 2011-05-16 05:23:01

+0

這是完全不同的問題。你想要的是重構你的代碼,而不是使用不同的技術;不要使用更大的錘子,改變使用方式。 – alex 2011-05-16 05:25:49

回答

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行長,而不是幾十。把事情分解成小的,可重複使用的,最重要的是可讀的塊,它們用明確的名稱聲明它們的意圖,這樣你的代碼就會更像你的思維過程,而不是像一連串的魔法咒語,它們會讓計算機做你所想希望它能做到。

+0

「一系列不可思議的咒語讓某種程度上使計算機做你想做的事。」 - 大聲笑。感謝您的幫助和建議,@Domenic。非常感激。 :) – 2011-05-16 05:33:28

2

代碼有效嗎?你有什麼新的要求來實施?你有沒有更重要的事情要做?

如果它沒有損壞,請不要修復它。你只是要引入錯誤。

+0

「如果它沒有損壞,請不要修復它。」 - 我同意。但我只是覺得這是這個,我不知道。我只是認爲應該是/使用XML/Linq更好的選擇。不,我真的沒有更好的辦法,是的,我需要添加更多的屬性,如地圖和時區信息。但我已經可以做到了。我只是希望有更好的方式來做我已經做的事情。 – 2011-05-16 06:14:45

+1

毫無疑問,有,並且我支持學習新的方法來做事和改進。但請注意,您很可能*會引入錯誤。 – 2011-05-16 06:22:15

+0

@Kirk Broadhurst:除非您編寫單元測試,以便您可以無懼編碼! – Domenic 2011-05-16 14:07:17