1

我已经尝试按照Joost Van Schaik 关于墓碑的文章中的步骤进行操作,但无法让它为我工作。毫无疑问,我做错了什么。在我的视图模型中:

private string _foobar ="init";

public string testStr
{
    get
    {
        return _foobar;
    }

    set
    {
        _foobar = value;
    }
}

在我的页面中:

<TextBox x:Name="tBoxTest" Text="{Binding testStr, Mode=TwoWay}" />

在应用程序运行时,更改 tBoxTest 中的值设置 _foobar 就好了,但是尝试对其进行序列化,就好像它忘记了实例一样???任何帮助将不胜感激。

4

2 回答 2

1

通过执行以下操作,我能够让墓碑工作,同时让我的所有 ViewModel 都可以看到一个对象:

在 Model 类中,我添加了:

private static Model1 _instance;
public static Model1 Instance
{
    get { return _instance; }
    set { _instance = value; }
}

public static void CreateNew()
{
    if (_instance == null)
    {
        _instance = new Model1();

        _instance.FirstString = "init";
    }
}

然后在 ApplicationExtensions.cs 我添加了:

  public static void SaveToIsolatedStorage(this Application app, Model1 model)
    {
        var dataFileName = GetIsFile((model.GetType()));
        using (var userAppStore =
                 IsolatedStorageFile.GetUserStoreForApplication())
        {
            if (userAppStore.FileExists(dataFileName))
            {
                userAppStore.DeleteFile(dataFileName);
            }
            using (var iss = userAppStore.CreateFile(dataFileName))
            {
                SilverlightSerializer.Serialize(model, iss);
            }
        }
    }

在 App.xaml.cs 我将 LoadModel() 更改为:

private void LoadModel()
{
    try
    {
        Model1.Instance = this.RetrieveFromIsolatedStorage<Model1>();
    }
    catch (Exception) { }

    if (Model1.Instance == null) Model1.CreateNew();
}

这一切都使我的 ViewModel 文件中的这些工作:

public string TestStr
{
    get
    {
        return Model1.Instance.FirstString;
    }

    set
    {
        Model1.Instance.FirstString = value;
    }
}

我的意思是,Model1 对象正在被序列化并且墓碑正在工作——至少我得到了我认为我想要的东西。我已经通过在应用程序、手机设置之间导航、关闭和打开手机、锁定它并在另一部手机的应用程序中调用它进行了很多测试。反序列化时的性能很棒。我可以使用 vars。

也就是说,Van Schaik 先生回复了一个帮助请求:“如果你是从 MVVMLight ViewModelBase 继承它,那么你应该像这样从你的 setter 调用 RaisePropertyChanged:

私人字符串_foobar =“初始化”;

公共字符串 TestStr { 获取 { 返回 _foobar; }

    set
    {
         RaisePropertyChanged("TestStr");
        _foobar = value;
    }
}

RaisePropertyChanged 通知任何监听视图(即绑定到它的 TextBox)属性已更改并且应该更新其内容。这是一个至关重要的机制。”

因此,我将使用我最初尝试的方法,但添加 RaisePropertyChanged 以查看其作用。

更新

尽管我在我的 MainViewModel.cs 文件中实现了 RaisedPropertyChanged(使用代码片段 mvvminpc),但它仍然对序列化在 ViewModel 中创建的任何内容没有任何影响(尽管它可能对其他事物一样好)。我可能仍然做错了什么,但这也可能是因为视图模型继承自受保护的类(来自 Laurent Bugnion 的回答)。我(非常不情愿地)尝试将该类从受保护的类更改为公共类并重新编译,但这对我的情况没有帮助,我讨厌分叉这样的引用库。无论如何,我现在只是在 App.xaml.cs 中创建 Model1 实例。似乎工作。在此期间,我修改了 Van Schaik 的一种方法以接受任何类型的对象:

public static void SaveToIsolatedStorage<T>(this Application app, T obj)
where T : class
{
    var dataFileName = GetIsFile(typeof(T));
    using (var userAppStore =
                IsolatedStorageFile.GetUserStoreForApplication())
    {
        if (userAppStore.FileExists(dataFileName))
        {
            userAppStore.DeleteFile(dataFileName);
        }
        using (var iss = userAppStore.CreateFile(dataFileName))
        {
            SilverlightSerializer.Serialize(obj, iss);
        }
    }
}
于 2011-02-02T15:02:48.207 回答
0

从您发布的代码中没有即时答案。

我的调试建议是:

  • 如果你从那篇文章中完全复制了代码,那么在空的 catch 处理程序中添加一些东西(一个消息框?) - `catch (Exception){ }

  • 使用调试器在 LoadModel 和 SaveToIsolatedStorage 方法中放置断点

  • 使用这些断点单步执行加载和保存代码 - 代码是否正确加载和保存?

老实说,遇到这样的问题,自己做一点调查比在这里提问要好得多(IMO!)

于 2011-02-02T08:46:00.063 回答