2011-03-26 24 views
0

我發現一個工作代碼序列化的控件,但它沒有一個功能:有一個控件,控件有一個事件,保存後不保存。我怎麼解決這個問題?事件序列化

以下是代碼:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Reflection; 
using System.Runtime.Serialization; 
using System.Text; 
using System.Windows.Forms; 
using System.Xml; 
using System.Xml.Linq; 

namespace serial 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      // Save control 
      int i = 0; 
      foreach (XElement element in 
       panel1.Controls 
       .OfType<Control>() 
       .Select(ToXml)) 
      { 
       element.Save("Control" + i++ + ".xml"); 
      } 
     } 

     private static XElement ToXml(Control control) 
     { 
      Type controlType = control.GetType(); 

      var root = new XElement("Root", 

       new XAttribute("Type", controlType.AssemblyQualifiedName)); 

      PropertyInfo[] fieldInfos = controlType.GetProperties(BindingFlags.Public | BindingFlags.Instance); 
      foreach (PropertyInfo fieldInfo in fieldInfos) 
      { 
       if (fieldInfo.CanRead && fieldInfo.CanWrite && 
        fieldInfo.Name != "Font" && fieldInfo.Name != "Handle") 
       { 

        object content = fieldInfo.GetValue(control, null); 

        if (content != null && content.GetType().IsSerializable) 
        { 

         var serializer = new DataContractSerializer(content.GetType()); 
         var str = new StringBuilder(); 
         using (XmlWriter stream = XmlWriter.Create(str)) 
         { 

          serializer.WriteObject(stream, content); 
         } 

         XElement data = XElement.Parse(str.ToString()); 

         var element = new XElement("Property", 

          new XAttribute("Name", fieldInfo.Name), 

          new XAttribute("Type", fieldInfo.PropertyType.AssemblyQualifiedName) 
          , data); 

         root.Add(element); 
        } 
       } 
      } 
      return root; 
     } 
     private void button2_Click(object sender, EventArgs e) 
     { 
      panel1.Controls.Clear(); 
     } 

     private void button3_Click(object sender, EventArgs e) 
     { 
      // Clear panel 
      panel1.Controls.Clear(); 
      // Load control 
      IEnumerable<string> newControlsNames = Directory.EnumerateFiles(Environment.CurrentDirectory, "*.xml"); 
      Control[] newControls = newControlsNames 
       .Select(XElement.Load) 
       .Select(GetControl) 
       .Select(c => c as Control) 
       .ToArray(); 
      // Add control on panel 
      panel1.Controls.AddRange(newControls); 
     } 
     // get control from xml 
     private static object GetControl(XElement xml) 
     { 

      Type controlType = Type.GetType(xml.Attribute("Type").Value); 
      object control = Activator.CreateInstance(controlType);    
      IEnumerable<XElement> elements = xml.Elements("Property"); 
      foreach (XElement element in elements) 
      { 

       string name = element.Attribute("Name").Value;     
       Type type = Type.GetType(element.Attribute("Type").Value);     
       XNode first = element.Nodes().First();    
       var serializer = new DataContractSerializer(type); 
       object value; 
       using (var stream = new MemoryStream(Encoding.Default.GetBytes(first.ToString()))) 
       { 
        value = serializer.ReadObject(stream); 
       } 

       if (value != null) 
       { 
        PropertyInfo fieldInfo = controlType.GetProperty(name); 
        fieldInfo.SetValue(control, value, null); 
       } 
      } 
      return control; 
     } 

     private void button4_Click(object sender, EventArgs e) 
     { 
      MessageBox.Show("1"); 
     } 

     private void button5_MouseEnter(object sender, EventArgs e) 
     { 
      MessageBox.Show("2"); 
     } 
    } 
} 

編輯: 這裏是我的項目! http://www.fileserve.com/file/t7kUwWM

+0

* @討厭*,你究竟是什麼意思_「保存後不會保存[原文如此]」_?如果這是這裏的核心問題,這將有助於您提供更多的細節:XML文件是否寫入磁盤?保存期間或保存後是否發生異常?你能找出哪裏出錯的特定代碼行嗎?等等。 – stakx 2011-03-26 11:39:02

回答

0

evets的問題是,代表名單不能從類「外部」訪問。 有解決方法 - 必須使用反射和搜索類型作爲委託私人領域(我的意思是自定義委託不僅System.Delegate)和序列化目標對象和目標方法(通過System.Reflection.MethodInfo)的引用。

但是,這種解決方案是非常專有的,並不能保證所有情況下的正確行爲,因爲取決於對象的私有狀態。

+0

誰可以知道如何控制自己的事件?我有一個窗體,並在它的pictureBox與我可以移動和改變狀態的圖像。我想在關閉程序後保留數量和位置pictureBox並在下次啓動後恢復所有可能性! – Nasty 2011-03-26 19:04:41