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
};
}
}
}