ViewModels和IsolatedStorageSettings

时间:2012-03-15 15:00:25

标签: windows-phone-7 mvvm isolatedstorage

我正在开发一个显示天气信息的MVVM Windows手机应用程序。

当应用加载时,它会打开MainPage.xaml。它调用服务来获取天气信息并将该数据绑定到UI。返回Fahrenheit和Celcius信息,但只显示一个。

在设置页面上,用户可以选择以华氏度或摄氏度查看临时值。 用户可以随时更改此设置,并将其存储在IsolatedStorageSettings中。

我遇到的问题是: 当用户导航到“设置”页面并更改其对华氏度或Celcius的偏好时,此更改不会反映在主页面上。

这个问题让我开始在更广阔的背景下思考这个问题。我可以在任何MVVM应用程序中看到这是一个问题,其中显示取决于IsolatedStorage中的某些设置。任何时候更新IsoStore中的任何设置,ViewModels如何知道这一点?当我从NavigationSack导航回设置页面返回MainPage时,如何强制重新绑定页面?

我模型中的数据没有变化,只有我要显示的数据发生了变化。

我在这里错过了一些简单的东西吗?

提前致谢。 亚历

3 个答案:

答案 0 :(得分:0)

可能你有这样的代码:

public double DisplayTemperature
{
    get { return (IsCelsium) ? Celsium : Fahrenheit; }
}

IsCelsium是:

public double IsCelsium
{
    get { return (bool)settings["IsCelsium"]; }
    set { settings["IsCelsium"] = value; }
}

因此,您需要添加NotifyPropertyChanged事件以通知UI从DisplayTemperature属性中获取新值:

public double IsCelsium
{
    get { return (bool)settings["IsCelsium"]; }
    set
    {
        settings["IsCelsium"] = value;
        NotifyPropertyChanged("DisplayTemperature");
    }
}

答案 1 :(得分:0)

看看Caliburn Micro。你可以实现类似的东西或使用CM本身。使用CM时,我甚至不考虑这些东西,CM使它变得如此简单。

当您的ViewModel从Screen继承时,会触发您可以覆盖的生命周期事件。例如,OnInitialize在ViewModel第一次激活时触发,每次激活VM时都会触发OnActivate。还有OnViewAttached和OnViewLoaded。

这些方法是放置逻辑以填充或重新填充数据的理想场所。

CM还有一些special built in features允许用户轻松地将单个属性或整个对象图形逻辑删除为Iso或手机状态。

答案 2 :(得分:0)

好的,所以我想出了一个解决方案。在我开始之前,让我提供一些背景知识。我正在使用的应用程序使用MVVM Light和WP7Contrib。既然如此,我正在使用Funq for DI和MVVMLight Toolkit。在我发布我的初步问题之后,我更多地考虑了这个问题。我记得一段视频,我在MIX2011上观看了一段名为Deep Dive MVVM和Laurent Bugnion的视频

http://channel9.msdn.com/Events/MIX/MIX11/OPN03

在其中,他谈到了Windows Phone上的这个问题(查看模型并非同时存在)。有问题的部分开始于19分钟左右。

无论如何,在我记得并且意识到ViewModel定位器在App.xaml中暴露之后,这变成了一个难以解决的问题。当用户在设置页面上更改Fahrenheit / Celcius选项时,我只需通过ViewModelLocator获取对MainViewModel的引用,并重置绑定到UI的集合,从而导致绑定更新。

public bool AddOrUpdateValue(string Key, Object value)
    {
        bool valueChanged = false;

        // If the key exists
        if (settings.Contains(Key))
        {
            // If the value has changed
            if (settings[Key] != value)
            {
                // Store the new value
                settings[Key] = value;
                valueChanged = true;
            }
        }
            // Otherwise create the key.
        else
        {
            settings.Add(Key, value);
            valueChanged = true;
        }
        return valueChanged;
    }


    public bool ImperialSetting
    {
        get
        {
            return GetValueOrDefault<bool>(ImperialSettingKeyName, ImperialSettingDefault);
        }
        set
        {
            if (AddOrUpdateValue(ImperialSettingKeyName, value))
            {
                Save();
                RaisePropertyChanged("ImperialSettingText");
                var vml = new ViewModelLocator();
                vml.MainViewModel.Cities = (App.Current as App).Cities;
            }
        }
    }

我没有意识到我可以通过ViewModelLocator访问viewModel,这是一个错误。希望这篇文章可以节省别人在这个问题上烧掉的时间。