保存WPF ViewModel当前状态

时间:2018-01-23 14:13:28

标签: c# .net wpf mvvm

在我的WPF应用程序中,ViewModel具有很少的属性,observableCollections等。 当应用关闭或保存点击时,如何将当前状态保存为文件 我应该使用[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); }
    }
}

2 个答案:

答案 0 :(得分:2)

最佳方法取决于您的要求。例如,您可以使用内置的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的引用。有关详细信息,请参阅以下博文:https://www.bytefish.de/blog/enum_datacontractjsonserializer/

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

答案 1 :(得分:1)

持久存在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更改为您的应用程序所独有。