【问题标题】:MVVM-Light and WP7 ViewModel tombstoning isn't workingMVVM-Light 和 WP7 ViewModel 墓碑不起作用
【发布时间】:2011-02-02 00:32:54
【问题描述】:

我已尝试按照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 就好了,但是尝试对其进行序列化,就好像它忘记了实例一样???任何帮助将不胜感激。

【问题讨论】:

  • 您已经展示了您的属性的代码,看起来不错,但是您是否实现了解决方案的其余部分,以便在 Activated 和 @ 中相应地实际序列化和反序列化视图模型的实例987654325@事件?
  • 是的,我有。我应该在这篇文章中说清楚。我试图专注于一个有问题的领域。

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


【解决方案1】:

通过执行以下操作,我能够让 tombstoning 工作,同时让我的所有 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 ="init";

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

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

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

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

更新

虽然我在我的 MainViewModel.cs 文件中实现了 RaisedPropertyChanged(使用代码 sn-p mvvminpc),但它仍然对序列化在 ViewModel 中创建的任何内容没有任何影响(尽管它可能对其他事物一样好)。我可能仍然做错了什么,但也可能是因为视图模型继承自受保护的类 (answer from 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);
        }
    }
}

【讨论】:

    【解决方案2】:

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

    我的调试建议是:

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

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

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

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

    【讨论】:

    • 我是在 Stack Overflow 上发帖的新手,所以让我提一下,除非我尝试了其他所有方法,否则我永远不会发布问题。我做了上面提到的所有这些事情,用谷歌搜索了它,下载并搜索了我找到的 6 个样本。我什至考虑切换到 Caliburn Micro,因为它确实有解决方案。但我喜欢 MVVM-Light 并且已经在它上面投入了时间。我仅发布该代码的假设是其他人会完成本文中的所有步骤。阅读下面的帖子,了解我的一种解决方案和进一步调查。
    • 我想这将是我提供答案的上面的帖子。 (我选择回答它,而不是仅仅添加到我原来的帖子中,因为,嗯,这是对问题的回答。
    • 酷 - 我也是新手 - 只是认为在这种情况下最好的建议是放置一些断点来确定哪里出了问题。希望建议有所帮助。
    • 对不起,我不是故意要骂你的。事实上,我非常感谢您对我之前的问题的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多