Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将WPF中的对象序列化为XML_C#_Xml_Wpf_Serialization_Mvvm - Fatal编程技术网

C# 将WPF中的对象序列化为XML

C# 将WPF中的对象序列化为XML,c#,xml,wpf,serialization,mvvm,C#,Xml,Wpf,Serialization,Mvvm,因此,我正在使用MVVM在WPF中构建一个应用程序,并希望将各种对象模型数据保存为XML。使用我可以正确地将对象序列化为XML,但我遇到的问题是MVVM本身。 我无法在ViewModel代码的ICommand段中直接访问对象的模型(例如,当我点击save时,它会转到ViewModel中的ICommand方法)。 我已经将模型设置为可序列化的,我只是无法将其直接传递给我的序列化方法(它包含在它自己的静态助手类中),因此即使我没有收到“意外类型”的回音(因为VieWModel不可序列化),我也会得到

因此,我正在使用MVVM在WPF中构建一个应用程序,并希望将各种对象模型数据保存为XML。使用我可以正确地将对象序列化为XML,但我遇到的问题是MVVM本身。
我无法在ViewModel代码的ICommand段中直接访问对象的模型(例如,当我点击save时,它会转到ViewModel中的ICommand方法)。
我已经将模型设置为可序列化的,我只是无法将其直接传递给我的序列化方法(它包含在它自己的静态助手类中),因此即使我没有收到“意外类型”的回音(因为VieWModel不可序列化),我也会得到大量多余的垃圾,而不仅仅是正在序列化的模型类

我不确定我是否只是设计得不正确,或者是否有更好的方法,或者

另外,所有这些字段都只是被写入适当绑定的文本框控件中。现在,我只尝试使用名称字段,以避免其他数据类型无法正常工作时出现任何问题

编辑:根据注释中的要求,现在的目标只是能够在几个文本框(名字、中间名、姓氏)中写入一些文本位,然后将其保存到XML文件中

有关的总结模型:

namespace XMLaw.Model
{
    [Serializable]
    public class ClientModel
    {
        private string firstName { get; set; }
        private string middleName { get; set; }
        private string lastName { get; set; }
        private DateTime dateOfBirth { get; set; }
        private string ssn { get; set; } //Format: AA ## ## ## A, spaces optional
        private string address { get; set; }
        private string phone { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #region Name Properties
        public string FirstName
        {
            get { return firstName; }
            set
            {
                if( firstName != value )
                {
                    firstName = value;
                    OnPropertyChanged("FirstName");
                }
            }
        }
        public string MiddleName
        {
            get { return middleName; }
            set
            {
                if (middleName != value)
                {
                    middleName = value;
                    OnPropertyChanged("MiddleName");
                }
            }
        }
        public string LastName
        {
            get { return lastName; }
            set
            {
                if (lastName != value)
                {
                    lastName = value;
                    OnPropertyChanged("LastName");
                }
            }
        }
        #endregion

        public DateTime DateOfBirth
        {
            get { return dateOfBirth; }
            set
            {
                if ( dateOfBirth != value )
                {
                    DateTime dt = Convert.ToDateTime(value); //This will probably need to revisited since DateTime objects are fucking stupid
                    dateOfBirth = dt.Date;
                    OnPropertyChanged("DateOfBirth");
                }
            }
        }

        public string SSN
        {
            get { return ssn; }
            set
            {
                if( ssn != value)
                {
                    ssn = value;
                    OnPropertyChanged("SSN");
                }
            }
        }

        public string Address
        {
            get { return address; }
            set
            {
                if( address != value)
                {
                    address = value;
                    OnPropertyChanged("Address");
                }
            }
        }

        public string Phone
        {
            get { return phone; }
            set
            {
                if( phone != value )
                {
                    phone = value;
                    OnPropertyChanged("Phone");
                }
            }
        }

    }
}
以及所讨论的ViewModel(调用序列化的Save命令位于底部)

还有我无耻地从上面的链接中获取的Serailization方法

public static class Helper
{
    public static string Serialize<T>(this T value)
    {
        if (value == null)
        {
            return string.Empty;
        }
        try
        {
            var xmlserializer = new XmlSerializer(typeof(T));
            var stringWriter = new StringWriter();
            using (var writer = XmlWriter.Create(stringWriter))
            {
                xmlserializer.Serialize(writer, value);
                return stringWriter.ToString();
            }
        }
        catch (Exception ex)
        {
            throw new Exception("An error occurred", ex);
        }
    }
}
公共静态类帮助器
{
公共静态字符串序列化(此T值)
{
如果(值==null)
{
返回字符串。空;
}
尝试
{
var xmlserializer=新的xmlserializer(typeof(T));
var stringWriter=新的stringWriter();
使用(var writer=XmlWriter.Create(stringWriter))
{
serializer.Serialize(writer,value);
返回stringWriter.ToString();
}
}
捕获(例外情况除外)
{
抛出新异常(“发生错误”,例如);
}
}
}

将您的客户机型号更改为:

[Serializable]
    public class ClientModel
    {
        private string firstName;
        private string middleName;
        private string lastName;
        private DateTime dateOfBirth;
        private string ssn;
        private string address;
        private string phone;


        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #region Name Properties
        public string FirstName {
            get { return firstName; }
            set {
                if (firstName != value)
                {
                    firstName = value;
                    OnPropertyChanged("FirstName");
                }
            }
        }
        public string MiddleName {
            get { return middleName; }
            set {
                if (middleName != value)
                {
                    middleName = value;
                    OnPropertyChanged("MiddleName");
                }
            }
        }
        public string LastName {
            get { return lastName; }
            set {
                if (lastName != value)
                {
                    lastName = value;
                    OnPropertyChanged("LastName");
                }
            }
        }
        #endregion

        public DateTime DateOfBirth {
            get { return dateOfBirth; }
            set {
                if (dateOfBirth != value)
                {
                    DateTime dt = Convert.ToDateTime(value); //This will probably need to revisited since DateTime objects are fucking stupid
                    dateOfBirth = dt.Date;
                    OnPropertyChanged("DateOfBirth");
                }
            }
        }

        public string SSN {
            get { return ssn; }
            set {
                if (ssn != value)
                {
                    ssn = value;
                    OnPropertyChanged("SSN");
                }
            }
        }

        public string Address {
            get { return address; }
            set {
                if (address != value)
                {
                    address = value;
                    OnPropertyChanged("Address");
                }
            }
        }

        public string Phone {
            get { return phone; }
            set {
                if (phone != value)
                {
                    phone = value;
                    OnPropertyChanged("Phone");
                }
            }
        }

    }
用法:

 var xx = new ClientModel();
            xx.FirstName = "John";
            xx.LastName = "Smith";
            xx.DateOfBirth = DateTime.Now;

            var result = xx.Serialize();
public ICommand SaveCommand
        {
            get
            {
                if (btnSave == null)
                    btnSave = new Save();
btnSave.Model = this.ClientModel;

                return btnSave;
            }
            set { btnSave = value; }
        }
结果:

http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\“”> 约翰·史密斯 2016-07-11T00:00:00+02:00

编辑:

此代码:

public void Execute(object param)
            {
                ClientViewModel viewModel = (ClientViewModel)param;
                //TODO: Insert XML serialization and save to a file
                var xml = Helper.Serialize(param);


                //Placeholder to make sure the button works
                viewModel.DisplayMessage = "You clicked the button at " + DateTime.Now;
            }
应替换为以下内容:

public void Execute(object param)
            {
                ClientModel model= (ClientModel )param;
                //TODO: Insert XML serialization and save to a file
                var xml = Helper.Serialize(param);


                //Placeholder to make sure the button works
                viewModel.DisplayMessage = "You clicked the button at " + DateTime.Now;
            }
确保您的
Param
为ClientModel类型

我也强烈推荐你,让你了解

编辑2(命令Thingy):

用法:

 var xx = new ClientModel();
            xx.FirstName = "John";
            xx.LastName = "Smith";
            xx.DateOfBirth = DateTime.Now;

            var result = xx.Serialize();
public ICommand SaveCommand
        {
            get
            {
                if (btnSave == null)
                    btnSave = new Save();
btnSave.Model = this.ClientModel;

                return btnSave;
            }
            set { btnSave = value; }
        }

不要将属性用作
属性的支持字段(你真的这样做了吗)。请将你的
属性设置为私有的
字段。此外,你的
属性更改的事件无法序列化。请将其标记为
[非序列化]
你能给我一个例子说明你的意思吗“不要使用属性作为属性的支持字段”?这确实是我第一次尝试使用MVVM,我花了很长时间才找到一个不复杂的教程,这是我找到的唯一连贯的方法。@KoalaBear看到它在哪里写着
私有字符串firstName{get;set;}
?只要替换
{get;set;}
带分号:
private string firstName;
。这将属性转换为字段。属性具有get/set访问器;字段只是一个成员变量。无论您试图实现什么,这都不是实现的方法。如果您想描述您的目标,我们可能会为您提供更好、更简单的解决方案。此外,xml serialization在框架中有点糟糕。我总是使用NetDataContractSerializer或XamlServices.Save。它们处理对象图的效果比XmlSerializer好得多。两者都产生XML(第二种是xaml风格的XML).啊,是的。我现在明白我有多傻了。这并不能解决无法从ViewModel类“save”内部序列化对象的问题“但是,命令。后期编辑:无法将类型为'XMLaw.ViewModel.ClientViewModel'的对象强制转换为类型为'XMLaw.Model.ClientModel'。第一步:使用。另一种方法是,在
Save
-命令中实现
ClientModel
类型的属性,并将其设置为用于purpose@KoalaBear我已经为您做了一个快速而肮脏的修复。我编辑了Save类,使其具有一个接受ClientModel的构造函数,它不允许我以其他方式设置模型变量。我相信这是100%的错误方式做任何事情,但它做了我现在需要的,谢谢你的帮助。我将不得不重新埋头于其他文档中,以降低这一点。