2017-10-02 1 views
-2

Ich habe einige Code:C# Serialisierung UIElementCollection

public static UIElementCollection DeSerializeXAML(string filename) 
    { 
     // Load XAML from file. Use 'using' so objects are disposed of properly. 
     using (System.IO.FileStream fs = System.IO.File.Open(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read)) 
     { 
      return System.Windows.Markup.XamlReader.Load(fs) as UIElementCollection; //EXCEPTION 
     } 
    } 

    // Serializes any UIElement object to XAML using a given filename. 
    public static void SerializeToXAML(UIElementCollection elements, string filename) 
    { 
     // Use XamlWriter object to serialize element 
     string strXAML = System.Windows.Markup.XamlWriter.Save(elements); 

     // Write XAML to file. Use 'using' so objects are disposed of properly. 
     using (System.IO.FileStream fs = System.IO.File.Create(filename)) 
     { 
      using (System.IO.StreamWriter streamwriter = new System.IO.StreamWriter(fs)) 
      { 
       streamwriter.Write(strXAML); 
      } 
     } 
    } 

    private void btnSave_Click(object sender, RoutedEventArgs e) 
    { 
     SaveFileDialog dlg = new SaveFileDialog(); 
     dlg.FileName = "UIElement File"; // Default file name 
     dlg.DefaultExt = ".xaml"; // Default file extension 
     dlg.Filter = "Xaml File (.xaml)|*.xaml"; // Filter files by extension 

     // Show save file dialog box 
     Nullable<bool> result = dlg.ShowDialog(); 

     // Process save file dialog box results 
     if (result == true) 
     { 
      // Save document 
      string filename = dlg.FileName; 
      SerializeToXAML(myCanvas.Children, filename); 
     } 
    } 

    private void btnLoad_Click(object sender, RoutedEventArgs e) 
    { 
     Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); 
     dlg.DefaultExt = ".xaml"; // Default file extension 
     dlg.Filter = "Xaml File (.xaml)|*.xaml"; // Filter files by extension 

     // Show open file dialog box 
     Nullable<bool> result = dlg.ShowDialog(); 

     // Process open file dialog box results 
     if (result == true) 
     { 
      string filename = dlg.FileName; 
      UIElementCollection elements = DeSerializeXAML(filename) as UIElementCollection; 

      // Add all child elements (lines, rectangles etc) to canvas 
      myCanvas.Children.Clear(); 
      foreach (UIElement el in elements) 
      { 
       myCanvas.Children.Add(el); 
      } 
     } 
    } 

, die mit Serialisierung funktioniert gut, aber wenn man deserialisieren, wird eine Ausnahme ausgelöst.

Text Ausnahme (übersetzt mit google): System.Windows.Controls.UIElementCollection „Sie haben keinen geeigneten Konstruktor für die Art finden“.

"Sie können die Argumente oder FactoryMethod Direktiven verwenden, um diesen Typ zu generieren.": Zeilennummer "1" und Position in Zeile "22".

Antwort

0

UIElementCollection ist nicht für die Serialisierung vorgesehen. Es sollte beim Erstellen eines WPF-visuellen Baums verwendet werden.

+0

Letztere ausschließen, obwohl die ehemalige nicht. Vielleicht möchte er WPF visuelle Bäume exportieren. – SlapY

1

Eine UIElementCollection Instanz ist an eine bestimmte Visual gebunden, und als solche ist es nicht für die Serialisierung geeignet (wie @ kostya-k weist darauf hin). Die Deserialisierungslogik weiß nicht, wie man eine neue UIElementCollection erstellt, weil sie nicht weiß, welche Visual sie zuordnen soll. Das Erstellen einer neuen Sammlung ist sowieso sinnlos, da Sie die Werte einfach an myCanvas.Children übertragen.

Die gute Nachricht ist, dass Sie eine XamlObjectWriter verwenden können myCanvas.Childrendirekt statt instantiatating eine neue Kollektion zu füllen:

public static void DeSerializeXAML(UIElementCollection elements, string filename) 
{ 
    var context = System.Windows.Markup.XamlReader.GetWpfSchemaContext(); 

    var settings = new System.Xaml.XamlObjectWriterSettings 
         { 
          RootObjectInstance = elements 
         }; 

    using (var reader = new System.Xaml.XamlXmlReader(filename)) 
    using (var writer = new System.Xaml.XamlObjectWriter(context, settings)) 
    { 
     System.Xaml.XamlServices.Transform(reader, writer); 
    } 
} 

private void btnLoad_Click(object sender, RoutedEventArgs e) 
{ 
    Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); 
    dlg.DefaultExt = ".xaml"; // Default file extension 
    dlg.Filter = "Xaml File (.xaml)|*.xaml"; // Filter files by extension 

    // Show open file dialog box 
    Nullable<bool> result = dlg.ShowDialog(); 

    // Process open file dialog box results 
    if (result == true) 
    { 
     string filename = dlg.FileName; 
     myCanvas.Children.Clear(); 
     DeSerializeXAML(myCanvas.Children, filename); 
    } 
}