2012-05-25 1 views
0

Je suis en train d'atteindre cet objectif: sauver l'état de l'application Silverlight au isolateduserstorage, afin de le recharger au prochain démarrage. Je dois stocker un List ObservableCollection<UIElement>, le UIElements sont créés par une usine (en fait, je suis en train de créer là Shapes).sérialisation XML Silverlight UIElement

Le problème est que Serialization jette une exception (que vous trouverez ci-dessous). J'ai la moindre idée ce que le problème pourrait être (Serialization ne marche pas savoir comment stocker UIElements (?)), Cependant, je ne sais pas comment résoudre ce problème.

Exception:

System.InvalidOperationException was unhandled by user code 
    Message=There was an error generating the XML document. 
    StackTrace: 
     bei System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id) 
     bei System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle) 
     bei System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces) 
     bei System.Xml.Serialization.XmlSerializer.Serialize(Stream stream, Object o, XmlSerializerNamespaces namespaces) 
     bei System.Xml.Serialization.XmlSerializer.Serialize(Stream stream, Object o) 
     bei Dojo_2_wi10b012.ViewModel.ViewModel.StoreContent() 
     bei Dojo_2_wi10b012.ViewModel.RelayCommand.Execute(Object parameter) 
     bei System.Windows.Controls.Primitives.ButtonBase.ExecuteCommand() 
     bei System.Windows.Controls.Primitives.ButtonBase.OnClick() 
     bei System.Windows.Controls.Button.OnClick() 
     bei System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) 
     bei System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e) 
     bei MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName, UInt32 flags) 
    InnerException: System.InvalidOperationException 
     Message=The type System.Windows.Shapes.Ellipse was not expected. Use the XmlInclude attribute to specify types that are not known statically. 
     StackTrace: 
      bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterObservableCollection1.Write12_UIElement(String n, String ns, UIElement o, Boolean isNullable, Boolean needType) 
      bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterObservableCollection1.Write13_ArrayOfUIElement(Object o) 
     InnerException: 

ViewModel: (partie importante est la méthode "StoreContent()")

using System; 
using System.Net; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Ink; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 
using Dojo_2_wi10b012.Model; 
using System.ComponentModel; 
using System.Reflection; 
using System.IO.IsolatedStorage; 
using System.IO; 
using System.Xml.Serialization; 

namespace Dojo_2_wi10b012.ViewModel 
{ 
    public class ViewModel : INotifyPropertyChanged 
    { 
     private List<UIElement> _shapeList = new List<UIElement>(); 
     private ShapeFactory theFactory = new ShapeFactory(); 
     private ObservableCollection<UIElement> _elements = new ObservableCollection<UIElement>(); 
     private UIElement _selectedItem ; 
     private UIElement _alteredSelectedItem; 
     private ObservableCollection<KeyValuePair<string, Color>> _theColors = new ObservableCollection<KeyValuePair<string, Color>>(); 
     private KeyValuePair<string, Color> _selectedBrush = new KeyValuePair<string, Color>(); 
     private KeyValuePair<string, Color> _selectedStroke = new KeyValuePair<string, Color>(); 
     private SolidColorBrush _selectedBrushBrush = new SolidColorBrush(); 
     private SolidColorBrush _selectedStrokeBrush = new SolidColorBrush(); 
     private int _heightText; 
     private int _widthText; 
     private string filename = "uielements"; //for isolatedstorage   

     #region EventHandler 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected void NotifyPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
     #endregion 

     public ViewModel() 
     { 
      GetShapesCommand = new RelayCommand(GetShapes); 
      GetShapesCommand.IsEnabled = true; 
      LoadColors(); 
      ChangeShapeCommand = new RelayCommand(ChangeShape); 
      ChangeShapeCommand.IsEnabled = true; 
      StoreContentCommand = new RelayCommand(StoreContent); 
      StoreContentCommand.IsEnabled = true; 
     } 

     #region properties 

     public int HeightText 
     { 
      get { return _heightText; } 
      set 
      { 
       _heightText = value; 
       NotifyPropertyChanged("HeightText"); 
      } 
     } 

     public int WidthText 
     { 
      get { return _widthText; } 
      set 
      { 
       _widthText = value; 
       NotifyPropertyChanged("WidthText"); 
      } 
     } 

     public SolidColorBrush SelectedBrushBrush 
     { 
      get { return _selectedBrushBrush; } 
      set 
      { 
       _selectedBrushBrush = value; 
       NotifyPropertyChanged("SelectedBrushBrush"); 
      } 
     } 

     public SolidColorBrush SelectedStrokeBrush 
     { 
      get { return _selectedStrokeBrush; } 
      set 
      { 
       _selectedStrokeBrush = value; 
       NotifyPropertyChanged("SelectedStrokeBrush"); 
      } 
     } 

     public KeyValuePair<string, Color> SelectedBrush 
     { 
      get { return _selectedBrush; } 
      set 
      { 
       _selectedBrush = value; 
       NotifyPropertyChanged("SelectedBrush"); 
       SelectedBrushBrush = new SolidColorBrush(value.Value); 
      } 
     } 

     public KeyValuePair<string, Color> SelectedStroke 
     { 
      get { return _selectedStroke; } 
      set 
      { 
       _selectedStroke = value; 
       NotifyPropertyChanged("SelectedStroke"); 
       SelectedStrokeBrush = new SolidColorBrush(value.Value); 
      } 
     } 

     public ObservableCollection<KeyValuePair<string, Color>> TheColors 
     { 
      get { return _theColors; } 
      set 
      { 
       _theColors = value; 
       NotifyPropertyChanged("TheColors"); 
      } 
     } 

     public List<UIElement> ShapeList 
     { 
      get { return _shapeList; } 
      set 
      { 
       _shapeList = value; 
       NotifyPropertyChanged("ShapeList"); 
      } 
     } 

     public ObservableCollection<UIElement> Elements 
     { 
      get { return _elements; } 
      set 
      { 
       _elements = value; 
       NotifyPropertyChanged("Elements"); 
      } 
     } 

     public UIElement SelectedItem 
     { 
      get { return _selectedItem; } 
      set 
      { 
       _selectedItem = value; 
       NotifyPropertyChanged("SelectedItem"); 
      } 
     } 

     public UIElement AlteredSelectedItem 
     { 
      get { return _alteredSelectedItem; } 
      set 
      { 
       _alteredSelectedItem = value; 
       NotifyPropertyChanged("AlteredSelectedItem"); 
      } 
     } 

     public RelayCommand GetShapesCommand { get; private set; } 
     public RelayCommand ChangeShapeCommand { get; private set; } 
     public RelayCommand StoreContentCommand { get; private set; } 


     #endregion 

     #region PrivateMethods 
     private void GetShapes() 
     { 
      UIElement temp = theFactory.ProduceShape(); 
      temp.MouseLeftButtonDown += Handle_MouseDown; 
      temp.MouseMove += Handle_MouseMove; 
      temp.MouseLeftButtonUp += Handle_MouseUp; 
      temp.MouseRightButtonDown += Handle_RightMouseDown; 
      ShapeList.Add(temp); //add the new shape to the list where we store the shapes 
      Elements.Add(temp); 
     } 

     private void ChangeShape() 
     { 
      AlteredSelectedItem = SelectedItem; 
      Shape temp = FigureOutShape(AlteredSelectedItem); 
      double debugheight = temp.Height; 
      double debugwidth = temp.Width; 
      temp.Height = HeightText; 
      temp.Width = WidthText; 
      temp.Fill = SelectedBrushBrush; 
      temp.Stroke = SelectedStrokeBrush; 
      SelectedItem = (UIElement)temp; 
     } 

     private Shape FigureOutShape(UIElement input) 
     { 
      if (input != null) 
      { 
       if (input is Ellipse) 
       { 
        return (Ellipse)input; 
       } 
       else { return (Rectangle)input; } 
      } 
      else //default if the user hasn't selected a shape 
       return new Ellipse() 
       { 
        Width = 25, 
        Height = 25, 
        Stroke = new SolidColorBrush(Colors.Green), 
        Fill = new SolidColorBrush(Colors.DarkGray), 
        StrokeThickness = 2, 
        Visibility = Visibility.Visible, 
        Cursor= Cursors.Hand, 
        Margin = new Thickness(25, 30, 0, 0) //define initial position on canvas randomly 
       }; 
     } 

     private void StoreContent() 
     { 
      //Hint from Mr. Eckkrammer (wiki): 
      using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication()) 
      { 
       IsolatedStorageFileStream isoRegisterFileStream; 

       isoRegisterFileStream = new IsolatedStorageFileStream(filename, FileMode.Create, isf); 

       XmlSerializer serializer = new XmlSerializer(Elements.GetType()); 

       serializer.Serialize(isoRegisterFileStream, Elements); 

       //close file stream 
       isoRegisterFileStream.Close(); 
      } 

     } 

     private void LoadContent() 
     { 
      /* 
      try 
      { 
      Elements as ObservableCollection<UIElement> = IsolatedStorageSettings.ApplicationSettings(filename); 
      } 
      catch 
      { 
      //no idea what to do here... 
      } 
      */ 
      using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication()) 
      { 
       using (IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(filename, FileMode.Open, isf)) 
       { 
        using (StreamReader sr = new StreamReader(isfs)) 
        { 

         // string lineOfData = String.Empty; 
         // while ((lineOfData = sr.ReadLine()) != null) 
         // data += lineOfData; 

         //no idea what to do here... 

        } 
       } 
      } 


     } 



     //when the user right clicks a shape, the "selectedItem" will be updated 
     private void Handle_RightMouseDown(object sender, MouseEventArgs args) 
     { 
      UIElement item = sender as UIElement; 
      SelectedItem = item; 
     } 

     private void LoadColors() 
     { 
      //unfortunately I have no idea how to do the following automatically, so I need to do it by hand :-(
      TheColors.Add(new KeyValuePair<string,Color>("Black",Colors.Black)); 
      TheColors.Add(new KeyValuePair<string,Color>("Blue",Colors.Blue)); 
      TheColors.Add(new KeyValuePair<string,Color>("Brown",Colors.Brown)); 
      TheColors.Add(new KeyValuePair<string,Color>("Cyan",Colors.Cyan)); 
      TheColors.Add(new KeyValuePair<string,Color>("DarkGray",Colors.DarkGray)); 
      TheColors.Add(new KeyValuePair<string,Color>("Gray",Colors.Gray)); 
      TheColors.Add(new KeyValuePair<string,Color>("Green",Colors.Green)); 
      TheColors.Add(new KeyValuePair<string, Color>("LightGray", Colors.LightGray)); 
      TheColors.Add(new KeyValuePair<string,Color>("Magenta",Colors.Magenta)); 
      TheColors.Add(new KeyValuePair<string,Color>("Orange",Colors.Orange)); 
      TheColors.Add(new KeyValuePair<string,Color>("Purple",Colors.Purple)); 
      TheColors.Add(new KeyValuePair<string,Color>("Red",Colors.Red)); 
      TheColors.Add(new KeyValuePair<string,Color>("White",Colors.White)); 
      TheColors.Add(new KeyValuePair<string,Color>("Yellow",Colors.Yellow)); 
     } 
     #endregion 

     #region DragAndDropImplementation 

     private bool isMouseCaptured; 
     private double mouseVerticalPosition; 
     private double mouseHorizontalPosition; 

     private void Handle_MouseDown(object sender, MouseEventArgs args) 
     { 
      UIElement item = sender as UIElement; 
      mouseVerticalPosition = args.GetPosition(null).Y; 
      mouseHorizontalPosition = args.GetPosition(null).X; 
      isMouseCaptured = true; 
      item.CaptureMouse(); 
     } 

     private void Handle_MouseMove(object sender, MouseEventArgs args) 
     { 
      UIElement item = sender as UIElement; 
      if (isMouseCaptured) 
      { 

       // Calculate the current position of the object. 
       double deltaV = args.GetPosition(null).Y - mouseVerticalPosition; 
       double deltaH = args.GetPosition(null).X - mouseHorizontalPosition; 
       double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty); 
       double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty); 

       // Set new position of object. 
       item.SetValue(Canvas.TopProperty, newTop); 
       item.SetValue(Canvas.LeftProperty, newLeft); 

       // Update position global variables. 
       mouseVerticalPosition = args.GetPosition(null).Y; 
       mouseHorizontalPosition = args.GetPosition(null).X; 
      } 
     } 

     private void Handle_MouseUp(object sender, MouseEventArgs args) 
     { 
      UIElement item = sender as UIElement; 
      isMouseCaptured = false; 
      item.ReleaseMouseCapture(); 
      mouseVerticalPosition = -1; 
      mouseHorizontalPosition = -1; 
     } 
     #endregion 
    } 
} 

ShapeFactory.cs:

namespace Dojo_2_wi10b012.Model 
{ 
    public class ShapeFactory 
    { 
     Random ran; 
     Random xy; 
     int thick = 5; 
     public ShapeFactory() 
     { 
      ran = new Random(); 
      xy = new Random(); 
     } 

     public Shape ProduceShape() 
     { 
      int guess = ran.Next(0, 4); 
      int height = ran.Next(20, 80); 
      int width = ran.Next(20, 80); 
      int x = xy.Next(0,300); 
      int y = xy.Next(25,300); 

      if (guess == 0)//Ellipse 
       return new Ellipse() 
       { 
        Width = height, 
        Height = width, 
        Stroke = new SolidColorBrush(Colors.Green), 
        Fill = new SolidColorBrush(Colors.DarkGray), 
        StrokeThickness = thick, 
        Visibility = Visibility.Visible, 
        Cursor= Cursors.Hand, 
        Margin = new Thickness(x, y, 0, 0) //define initial position on canvas randomly 
       }; 
      else if (guess == 1) //Rectangle 
       return new Rectangle() 
       { 
        Width = height, 
        Height = width, 
        Stroke = new SolidColorBrush(Colors.Brown), 
        Fill = new SolidColorBrush(Colors.LightGray), 
        StrokeThickness = thick, 
        Visibility = Visibility.Visible, 
        Cursor = Cursors.Hand, 
        Margin = new Thickness(x, y, 0, 0) //define initial position on canvas randomly 
       }; 
      else if (guess == 2) //Square 
       return new Ellipse() 
       { 
        Width = height, 
        Height = height, 
        Stroke = new SolidColorBrush(Colors.Red), 
        StrokeThickness = thick, 
        Fill = new SolidColorBrush(Colors.Orange), 
        Visibility = Visibility.Visible, 
        Cursor = Cursors.Hand, 
        Margin = new Thickness(x, y, 0, 0) //define initial position on canvas randomly 
       }; 
      else //Circle 
       return new Rectangle() 
       { 
        Width = height, 
        Height = height, 
        Stroke = new SolidColorBrush(Colors.Blue), 
        StrokeThickness = thick, 
        Fill = new SolidColorBrush(Colors.Cyan), 
        Visibility = Visibility.Visible, 
        Cursor = Cursors.Hand,      
        Margin = new Thickness(x, y, 0, 0) //define initial position on canvas randomly 
       }; 
     } 
    } 
} 

Répondre

1

UIElement ne prend pas en charge la sérialisation , vous devrez le sérialiser en XML sous forme de chaîne, l'enregistrer dans un stockage isolé ou dans une base de données, le désérialiser du XML vers le viewmodel.

0

Avez-vous essayé d'utiliser les services de sérialisation Xaml? Si vous êtes de/sérialisation du contenu xaml, il est préférable d'utiliser ceux-ci à la place de la sérialisation XML standard. This blog décrit tout.