MVVM-Light和WP7 ViewModel墓碑不起作用

时间:2011-02-02 00:32:55

标签: serialization windows-phone-7 viewmodel mvvm-light tombstoning

我已尝试按照Joost Van Schaik's article on tombstoning中的步骤操作,但无法让它为我工作。我毫无疑问做错了什么。在我的ViewModel中:

private string _foobar ="init";

public string testStr
{
    get
    {
        return _foobar;
    }

    set
    {
        _foobar = value;
    }
}

在我的页面中:

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

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

2 个答案:

答案 0 :(得分: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对象被序列化并且逻辑删除正在工作 - 至少我得到了我想要的东西。我通过在应用程序,手机设置之间导航,关闭和打开手机,锁定它并在另一部手机的应用程序中调用它来测试它。反序列化时的性能很好。我可以与变种合作。

那就是说,Van Schaik先生回复了一个请求帮助:“如果你从MVVMLight ViewModelBase继承子类,那么你应该从你的setter中调用RaisePropertyChanged: < / p>

private string _foobar =“init”;

公共字符串TestStr     {         得到         {             return _foobar;         }

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

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

所以我将使用我最初尝试的内容,但添加了RaisePropertyChanged以查看它的作用。

<强>更新

虽然我在MainViewModel.cs文件中实现了RaisedPropertyChanged(使用代码片段mvvminpc),但在序列化ViewModel中创建的任何内容时仍然没有效果(与其他东西一样好)。我可能仍然做错了,但也可能是因为视图模型继承自受保护的类(answer from Laurent Bugnion)。我(非常不情愿地)尝试将该类从protected更改为public并重新编译,但它在我的情况下没有帮助,我讨厌分叉这样的引用库。无论如何,我现在只是在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);
        }
    }
}

答案 1 :(得分:0)

根据你发布的代码,没有即时答案。

我的调试建议是:

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

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

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

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