Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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视图模型当前状态_C#_.net_Wpf_Mvvm - Fatal编程技术网

C# 保存WPF视图模型当前状态

C# 保存WPF视图模型当前状态,c#,.net,wpf,mvvm,C#,.net,Wpf,Mvvm,在我的WPF应用程序的视图模型中几乎没有属性、可观察的集合等。 当应用程序关闭或单击“保存”时,如何将其当前状态保存为文件 我应该使用[Serializable]实现吗 最好的方法是什么 public class CustomerViewModel { private Customer obj = new Customer(); public string TxtCustomerName { get { return obj.CustomerName;

在我的WPF应用程序的
视图模型中
几乎没有属性、可观察的集合等。 当应用程序关闭或单击“保存”时,如何将其当前状态保存为文件 我应该使用
[Serializable]
实现吗

最好的方法是什么

public class CustomerViewModel 
{
    private Customer obj = new Customer();

    public string TxtCustomerName
    {
        get { return obj.CustomerName; }
        set { obj.CustomerName = value; }
    }        

    public string TxtAmount
    {
        get { return Convert.ToString(obj.Amount) ; }
        set { obj.Amount = Convert.ToDouble(value); }
    }
}

最佳方法取决于您的需求。例如,您可以使用内置的
DataContractJsonSerializer
类序列化您的类,而无需修改该类:

CustomerViewModel vm = new CustomerViewModel();
//...

using (MemoryStream ms = new MemoryStream())
{
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(CustomerViewModel));
    ser.WriteObject(ms, vm);
    File.WriteAllText("save.txt", Encoding.UTF8.GetString(ms.ToArray()));
}
您需要添加对
System.Runtime.Serialization.dll
的引用。有关详细信息,请参阅以下博文:


流行的高性能第三方JSON序列化程序是othwerwise JSON.NET:。还有很多其他解决方案使用各种格式,无论是基于文本的还是二进制的。在复杂的情况下,您可能必须编写自己的自定义序列化程序。

最佳方法取决于您的需求。例如,您可以使用内置的
DataContractJsonSerializer
类序列化您的类,而无需修改该类:

CustomerViewModel vm = new CustomerViewModel();
//...

using (MemoryStream ms = new MemoryStream())
{
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(CustomerViewModel));
    ser.WriteObject(ms, vm);
    File.WriteAllText("save.txt", Encoding.UTF8.GetString(ms.ToArray()));
}
您需要添加对
System.Runtime.Serialization.dll
的引用。有关详细信息,请参阅以下博文:


流行的高性能第三方JSON序列化程序是othwerwise JSON.NET:。还有很多其他解决方案使用各种格式,无论是基于文本的还是二进制的。在复杂的情况下,您可能必须编写自己的自定义序列化程序。

对于持久化MVVM状态没有标准实践。您只需要选择一种格式,就像处理任何其他序列化问题一样。我个人非常喜欢使用Xaml,因为它是人类可读的,可以表示WPF应用程序中可能使用的大多数类型

示例代码,包含在视图模型的基类中:

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private static string RootStoragePath =>
        Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
            "YourApplication",
            "ViewState");

    protected string StateFilePath =>
       Path.Combine(RootStoragePath, this.GetType().Name + ".xaml");

    public void Save()
    {
        var fileName = StateFilePath;

        var directoryName = Path.GetDirectoryName(fileName);
        if (directoryName != null && !Directory.Exists(directoryName))
            Directory.CreateDirectory(directoryName);

        XamlServices.Save(fileName, this);
    }

    public void Load()
    {
        var fileName = StateFilePath;

        if (File.Exists(fileName))
        {
            using (var file = File.OpenRead(fileName))
            using (var reader = new XamlXmlReader(file))
            {
                var writer = new XamlObjectWriter(
                    reader.SchemaContext,
                    new XamlObjectWriterSettings { RootObjectInstance = this });

                using (writer)
                {
                    XamlServices.Transform(reader, writer);
                }
            }
        }
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
保存的状态如下所示:

<CustomerViewModel TxtAmount="3.5"
                   TxtCustomerName="Mike Strobel"
                   xmlns="clr-namespace:WpfTest;assembly=WpfTest" />


请注意,这是一个最小的示例。理想情况下,您对存储操作的错误处理将更加健壮。请确保将
RootStoragePath
更改为您的应用程序所特有的路径。

没有一个标准的做法来持久化MVVM状态。您只需要选择一种格式,就像处理任何其他序列化问题一样。我个人非常喜欢使用Xaml,因为它是人类可读的,可以表示WPF应用程序中可能使用的大多数类型

示例代码,包含在视图模型的基类中:

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private static string RootStoragePath =>
        Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
            "YourApplication",
            "ViewState");

    protected string StateFilePath =>
       Path.Combine(RootStoragePath, this.GetType().Name + ".xaml");

    public void Save()
    {
        var fileName = StateFilePath;

        var directoryName = Path.GetDirectoryName(fileName);
        if (directoryName != null && !Directory.Exists(directoryName))
            Directory.CreateDirectory(directoryName);

        XamlServices.Save(fileName, this);
    }

    public void Load()
    {
        var fileName = StateFilePath;

        if (File.Exists(fileName))
        {
            using (var file = File.OpenRead(fileName))
            using (var reader = new XamlXmlReader(file))
            {
                var writer = new XamlObjectWriter(
                    reader.SchemaContext,
                    new XamlObjectWriterSettings { RootObjectInstance = this });

                using (writer)
                {
                    XamlServices.Transform(reader, writer);
                }
            }
        }
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
保存的状态如下所示:

<CustomerViewModel TxtAmount="3.5"
                   TxtCustomerName="Mike Strobel"
                   xmlns="clr-namespace:WpfTest;assembly=WpfTest" />


请注意,这是一个最小的示例。理想情况下,您对存储操作的错误处理将更加健壮。请确保将
RootStoragePath
更改为您的应用程序所独有。

在这种情况下
customervicewmodel
应该具有
[Serializable]
属性?我可以在VM中保存这个
吗?正如我在回答中所说的,你不需要用任何属性来修饰你的类。我还向您展示了一个如何“保存”的示例。您可以将此代码放在任何需要的地方。
CustomerViewModel vm=new CustomerViewModel()创建了一个空对象,但我想保存当前状态,因此我使用了
,但它给出了一个错误
不是预期的。使用xmlclude或SoapInclude属性指定静态未知的类型。
如何返回?问题是如何使用反序列化对象,因为ViewModel反序列化非常类似。您只需使用博客文章中提到的ReadObject方法。在这种情况下,
CustomerServiceWModel
应该具有
[Serializable]
属性吗?我可以在VM中保存这个
吗?正如我在回答中所说的,你不需要用任何属性来修饰你的类。我还向您展示了一个如何“保存”的示例。您可以将此代码放在任何需要的地方。
CustomerViewModel vm=new CustomerViewModel()创建了一个空对象,但我想保存当前状态,因此我使用了
,但它给出了一个错误
不是预期的。使用xmlclude或SoapInclude属性指定静态未知的类型。
如何返回?问题是如何使用反序列化对象,因为ViewModel反序列化非常类似。你只需要使用博客文章中提到的ReadObject方法。我怎么能忽略一些属性
无法读取'Module+TwainImport\u Plugin'类型的对象。不支持嵌套类型。
听起来像是不应该包含的内容。任何不应持久化的属性都需要使用
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
进行注释。或者,您可以将其标记为
internal
protectedinternal
,并仅将持久化属性
设置为public
。如何忽略某些属性
无法读取“Module+TwainPort\U插件”类型的对象。不支持嵌套类型。
听起来像是不应该包含的内容。任何不应持久化的属性都需要使用
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
进行注释。或者,您可以将其标记为
internal
protectedinternal
,并仅将持久化属性
设置为public