ViewModels и IsolatedStorageSettings - PullRequest
       10

ViewModels и IsolatedStorageSettings

1 голос
/ 15 марта 2012

Я работаю над приложением MVVM для Windows Phone, которое отображает информацию о погоде.

Когда приложение загружается, оно открывает MainPage.xaml. Он вызывает службу для получения информации о погоде и привязывает эти данные к интерфейсу пользователя. Возвращается информация как по Фаренгейту, так и по Цельсию, но отображается только одна.

На странице настроек пользователь может выбрать для просмотра температуру в градусах Фаренгейта или Цельсия. Пользователь может изменить этот параметр в любое время и сохранить его в IsolatedStorageSettings.

У меня проблема в следующем: когда пользователь переходит на страницу настроек и меняет свои предпочтения по Фаренгейту или по Цельсию, это изменение не отражается на главной странице.

Эта проблема заставила меня задуматься об этом в более широком контексте. Я вижу, что это проблема в ЛЮБОМ приложении MVVM, где отображение зависит от некоторых настроек в IsolatedStorage. Каждый раз, когда любой параметр в IsoStore обновляется, откуда ViewModels узнает об этом? Когда я возвращаюсь обратно в NavigationStack со страницы настроек обратно на главную страницу, как я могу принудительно выполнить повторное связывание страницы?

Данные в моей модели не изменились, изменились только те данные, которые я хочу отобразить.

Я что-то упустил здесь?

Заранее спасибо. Alex

Ответы [ 3 ]

0 голосов
/ 15 марта 2012

Взгляните на Caliburn Micro .Вы можете реализовать нечто подобное или использовать сам CM.Когда я использую CM, я даже не думаю об этом, CM делает это так просто.

Когда ваша ViewModel наследует от Screen, возникают события жизненного цикла, которые вы можете переопределить.Например, OnInitialize запускается в первый раз, когда ViewModel активируется, а OnActivate запускается при каждой активации виртуальной машины.Есть также OnViewAttached и OnViewLoaded.

Эти методы являются идеальным местом для размещения логики для заполнения или повторного заполнения данных.

CM также имеет некоторые специальные встроенные функции дляпозволяя легко захоронить отдельное свойство или весь граф объектов в состояние Iso или телефона.

0 голосов
/ 16 марта 2012

хорошо, так что я придумаю решение. Прежде, чем я доберусь до этого, позвольте мне представить некоторую предысторию. Приложение, над которым я работаю, использует MVVM Light и WP7Contrib. В этом случае я использую Funq для DI и MVVMLight Toolkit. После того, как я опубликовал свой первоначальный вопрос, я немного подумал над ним. Я вспомнил видео, которое я смотрел некоторое время назад с MIX2011, под названием Deep Dive MVVM с Laurent Bugnion

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

В нем он говорит только об этой проблеме (просмотр моделей, не живущих одновременно) на Windows Phone. Речь идет о 19-минутной отметке.

В любом случае, после того, как я вспомнил об этом и понял, что локатор ViewModel выставлен в App.xaml, это стало тривиальной проблемой, которую нужно решить. Когда пользователь изменяет параметр Фаренгейта / Цельсия на странице настроек, я просто получаю ссылку на MainViewModel через ViewModelLocator и сбрасываю коллекцию, связанную с пользовательским интерфейсом, таким образом вызывая обновление привязок.

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;
            }
        }
    }

С моей стороны было ошибкой не осознавать, что я могу получить доступ к viewModel через ViewModelLocator. Надеюсь, этот пост сэкономит кому-то еще время, затраченное на эту проблему.

0 голосов
/ 15 марта 2012

Возможно, у вас есть такой код:

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

А IsCelsium составляет:

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

Таким образом, вам нужно добавить событие NotifyPropertyChanged, чтобы уведомить пользовательский интерфейс о получении новых значений из свойства DisplayTemperature:

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