2011-05-16 19 views
0

私はこのコードを正しく持っており、基本的にはXMLファイルを読み込み、いくつかのことをチェックして、適切なコントロールをCanvas(Panel)に配置します。もっとエレガントで効率的な方法ですか? (XML/Linq/Read&Write)

しかし、それは非常に長いです。または、私はそれが欲しいと思うよりも長い。そして、このコードは... 2〜3歳になりました。

私がしたいことは、XMLにLinqを使用することです。

  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ファイルへの書き込み

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ファイルからの読み込み

。それにはひとつの問題はありませんでした。しかし、私はXMLファイルを読み書きし、それらに対してlinqクエリを実行するために、より効率的な、より洗練された、エレガントな方法を必要としています。

私はいくつかのチュートリアル、および記事を読みましたが、私はかなりそれを取得できませんでした。あるWebサイトにはStreamWriterがありましたが、これは意味をなさないもので、Linqを使ってXMLファイルに書き込んだり読み込んだりする方法はたくさんあるようです。

すべての任意の助けを大幅に高く評価され、

は、私はあなたの問題は、間違ったクラスやツールを使用してはるかに少ないと思うし、あなたがメソッドを抽出して停止する方法を学ぶ必要があることをより多くのあなたに

+0

LINQ to XMLをまだ使用していませんか? XDocumentはSystem.Xmlにあります。 ** Linq **アセンブリ。 – alex

+0

ええ、それは私が見てきたこととはまったく異なります。それはとてもかさばる/醜い/長いです –

+0

これはまったく別の問題です。あなたが望むのは、あなたのコードをリファクタリングし、別のテクノロジーを使用することではありません。ハンマーを大きくしないでください。使用方法を変えてください。 – alex

答えて

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内でコードを2回繰り返すことができます。そのコードをメソッドに抽出できます。

方法は、一般数十、3--5行が長くないはずです。あなたのコードがより多くのあなたの思考プロセスのように読み、以下何とかコンピュータが何を間に合わせる魔法の呪文の長いシリーズのようになるように、明確な名前を持つ彼らの意図を宣言し、小さな再利用可能な、そして最も重要な読めるチャンクに物事を打破それが欲しい。

+0

"何とかコンピュータをあなたがしたいと思うようにする長い魔法の呪文。" - 笑。あなたの助けとアドバイス、@Domenicに感謝します。とても有難い。 :) –

2

コードが機能しますか?実装するための新しい要件がありますか?もっと重要なことは何もありませんか?

壊れていない場合は、修正しないでください。バグを導入するだけです。

+0

"壊れていない場合は修正しないでください。" - 同意する。しかし、私はちょうどこれがうーん、私は気にしないと感じています。私はちょうど/ XML/Linqを使って作業するより良い選択肢があると思います。いいえ、私は本当にいいことがありません。そして、私はMapsやTimeZoneのようなプロパティを追加する必要があります。しかし、私はすでにそれを行うことができます。私はすでに自分がやっていることをやるより良い方法があることを願っていました。 –

+1

間違いなく、私は物事と改善を行う新しい方法の学習をサポートしています。しかし、バグを導入する可能性が高いことに注意してください。 –

+0

@Kirk Broadhurst:単体テストを書かない限り、恐れなくコード化できる! – Domenic

関連する問題