Сохранение класса в XML
От: Sonyk91  
Дата: 25.10.11 18:59
Оценка:
Как правильно сохранить класс, со всеми объектами свойствами и так далее, пробывал сериализацию классов, но не получилось, т.к. стандартные классы в моем случае Border (как я понял не сериализован)? Может кто наставит на путь правильный!

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml.Serialization;
using System.Xml;



namespace ERModelData
{
    /// <summary>Сущность</summary>
    [Serializable]
    public class Essence : Border
    {
        /// <summary>Контрол отражающий имя сущности</summary>
        public Label name { get; set; }
        
        /// <summary>Панель содержащая атрибуты</summary>
        public StackPanel atributs { get; set; }

        //public LinkMarkers links { get; private set; }

        /// <summary>Констуктор класса сущность</summary>
        /// <param name="location">Верхний левый угол сущности</param>
        /// <param name="size">Размер сущности</param>
        public Essence(Point location, Size size, Canvas parent)
        {
            /// Настройка контрола отображения имени сущности
            name = new Label();          
            name.Content = "Essence1";
            name.MouseDoubleClick += new MouseButtonEventHandler(ChangeName);

            /// Настройка панели содержащая атрибуты сущности
            atributs = new StackPanel();
            atributs.Orientation = Orientation.Vertical;

            /// Настройка контрола для отображения атрибутов
            Expander atributsExpander = new Expander();
            atributsExpander.Header = "Атрибуты";
            atributsExpander.BorderBrush = Brushes.Black;
            atributsExpander.BorderThickness = new Thickness(0, 1, 0, 0);
            atributsExpander.Content = atributs;
            
            /// Настройка панели внутри сущности
            StackPanel inBorder = new StackPanel();
            inBorder.Orientation = Orientation.Vertical;
            name.Tag = inBorder.Children.Add(name);
            inBorder.Children.Add(atributsExpander);

            /// Контекстное меню
            ContextMenu EssenceMenu = new ContextMenu();

            Label addAtribute = new Label();
            addAtribute.Content = "Добавить атрибут";
            addAtribute.MouseLeftButtonUp += new MouseButtonEventHandler(AddAtribute);
            EssenceMenu.Items.Add(addAtribute);

            Label delEssence = new Label();
            delEssence.Content = "Удалить сущность";
            delEssence.MouseLeftButtonUp += new MouseButtonEventHandler(DelEssence);
            EssenceMenu.Items.Add(delEssence);

            this.ContextMenu = EssenceMenu;

            /// Настройка Сущности
            this.Background = Brushes.LightBlue;
            this.BorderBrush = Brushes.DarkBlue;
            this.BorderThickness = new Thickness(2);
            this.Width = size.Width;
            this.Height = size.Height;
            this.CornerRadius = new CornerRadius(10);
            Canvas.SetLeft(this, location.X);
            Canvas.SetTop(this, location.Y);
            this.Child = inBorder;
            parent.Children.Add(this);
            //links = new LinkMarkers(this);
        }

        /// <summary>Создание атрибута сущности</summary>
        void AddAtribute(object sender, MouseButtonEventArgs e)
        {
            Label name = new Label();
            name.Content = "atribut1";
            name.Name = "name";
            name.Tag = 1;
            name.MouseDoubleClick += new MouseButtonEventHandler(ChangeName);

            Image key = new Image();
            key.Source = new BitmapImage(new Uri(@"Icons/key.png", UriKind.Relative));
            key.Stretch = Stretch.Uniform;
            key.Width = 10;
            key.Height = 15;
            StackPanel panel = new StackPanel();
            panel.Orientation = Orientation.Horizontal;
            panel.Children.Add(key);
            panel.Children.Add(name);

            atributs.Children.Add(panel);
        }

        /// <summary>Удаление сущности</summary>
        void DelEssence(object sender, MouseButtonEventArgs e)
        {
            Canvas parent = (Canvas)this.Parent;
            parent.Children.Remove(this);
            parent.transform.Hiden();
        }

        ///////////////////////////////////////////////////////////////////////////////////
        //////                  Изменение имени сущности или атрибута               ///////
        ///////////////////////////////////////////////////////////////////////////////////

        /// <summary>Контрол для изменения имени сущности атрибута</summary>
        TextBox text = new TextBox();

        /// <summary>Начало редактирования</summary>
        void ChangeName(object sender, RoutedEventArgs e)
        {
            text.LostFocus += new RoutedEventHandler(EndChangeName);
            text.Tag = sender;
            Label label = (Label)sender;
            StackPanel parent = (StackPanel)label.Parent;
            ((Canvas)this.Parent).transform.IgnoreCall = true;
            ((Canvas)this.Parent).transform.Hiden();
            text.Text = label.Content.ToString();
            parent.Children.RemoveAt((int)label.Tag);
            parent.Children.Insert((int)label.Tag, text);
        }
        
        /// <summary>Завершение редактирования</summary>
        void EndChangeName(object sender, RoutedEventArgs e)
        {
            text.LostFocus -= EndChangeName;
            StackPanel parent = (StackPanel)text.Parent;
            Label label = (Label)text.Tag;
            label.Content = text.Text;
            ((Canvas)this.Parent).transform.IgnoreCall = false;
            ((Canvas)this.Parent).transform.Show(this);
            parent.Children.RemoveAt((int)label.Tag);
            parent.Children.Insert((int)label.Tag, label);
        }
    }
}
Re: Сохранение класса в XML
От: Elderos Россия  
Дата: 25.10.11 19:30
Оценка: 2 (1)
В общем случае только самому писать сериализацию.
Если нет биндингов и использования ресурсов, можно использовать XamlWriter.
Re[2]: Сохранение класса в XML
От: Sonyk91  
Дата: 26.10.11 03:14
Оценка:
Здравствуйте, Elderos, Вы писали:

E>В общем случае только самому писать сериализацию.

E>Если нет биндингов и использования ресурсов, можно использовать XamlWriter.

А как примерно, это должно выглядеть?
Re[3]: Сохранение класса в XML
От: Red Bird Россия  
Дата: 26.10.11 05:52
Оценка:
Здравствуйте, Sonyk91, Вы писали:

S>Здравствуйте, Elderos, Вы писали:


E>>В общем случае только самому писать сериализацию.

E>>Если нет биндингов и использования ресурсов, можно использовать XamlWriter.

S>А как примерно, это должно выглядеть?


Например, так:
public string ToXml()
{
 XmlWriter writer = null;
 StringBuilder sb = new StringBuilder();
 try
 {
  XmlWriterSettings settings = new XmlWriterSettings();
  settings.Indent = true;
  settings.IndentChars = ("\t");
  settings.Encoding = Encoding.UTF8;
  settings.OmitXmlDeclaration = true;
  writer = XmlWriter.Create(sb, settings);
  XamlWriter.Save(this, writer);
 }
 finally
 {
  if (writer != null)
  {
   writer.Close();
  }
 }
 string s = sb.ToString();
 return s;
}
Re[3]: Сохранение класса в XML
От: Elderos Россия  
Дата: 26.10.11 06:20
Оценка:
Здравствуйте, Sonyk91, Вы писали:

S>Здравствуйте, Elderos, Вы писали:


E>>В общем случае только самому писать сериализацию.

E>>Если нет биндингов и использования ресурсов, можно использовать XamlWriter.

S>А как примерно, это должно выглядеть?


Для нормальной сериализации надо отнаследовать класс от интерфейса IXmlSerializable и делать что-нибудь вроде такого:

public XmlSchema GetSchema()
{
    return null;
}

public void ReadXml(XmlReader reader)
{
    XDocument xdoc = XDocument.Load(reader);
    var root = xdoc.Root;

    Color color = (Color)XamlReader.Parse(root.Element("Color").Value);
    double thickness = double.Parse(root.Element("Thickness").Value.Replace(",", "."), CultureInfo.InvariantCulture);

    Initialize(color, thickness);
}

public void WriteXml(XmlWriter writer)
{
    writer.WriteElementString("Color", XamlWriter.Save(((SolidColorBrush)Line.Stroke).Color));
    writer.WriteElementString("Thickness", Line.StrokeThickness.ToString());
}


T.е. сериализовать и десериализовать все нужные свойства объекта.
Re: Сохранение класса в XML
От: Nikolay_P_I  
Дата: 26.10.11 08:59
Оценка:
Здравствуйте, Sonyk91, Вы писали:

S>Как правильно сохранить класс, со всеми объектами свойствами и так далее, пробывал сериализацию классов, но не получилось, т.к. стандартные классы в моем случае Border (как я понял не сериализован)? Может кто наставит на путь правильный!


К сказанному прочими добавлю, что если не интересует классический XML, то можно попробовать SOAP сериализатор или WCFный Contract сериализатор.

А если особого ничего не надо и силы тратить не хочется — можно просто сделать фальшивые свойства типа


[XMLIgnore]
public XXX MainProperty
{
  get { XXX.Parse(SerializedProperty) }
}
public YYY SerialisedProperty...


То есть — использовать одно, сериализовать другое.
Re[2]: Сохранение класса в XML
От: Elderos Россия  
Дата: 26.10.11 09:07
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Здравствуйте, Sonyk91, Вы писали:


S>>Как правильно сохранить класс, со всеми объектами свойствами и так далее, пробывал сериализацию классов, но не получилось, т.к. стандартные классы в моем случае Border (как я понял не сериализован)? Может кто наставит на путь правильный!


N_P>К сказанному прочими добавлю, что если не интересует классический XML, то можно попробовать SOAP сериализатор или WCFный Contract сериализатор.


N_P>А если особого ничего не надо и силы тратить не хочется — можно просто сделать фальшивые свойства типа



N_P>
N_P>[XMLIgnore]
N_P>public XXX MainProperty
N_P>{
N_P>  get { XXX.Parse(SerializedProperty) }
N_P>}
N_P>public YYY SerialisedProperty...
N_P>


N_P>То есть — использовать одно, сериализовать другое.


Тут в другом проблема: контролы WPF не сериализуются из коробки.
DataContractSerializer не спасет отца русской демократии в данным случае.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.