我正在开发一个显示天气信息的MVVM Windows手机应用程序。
当应用加载时,它会打开MainPage.xaml。它调用服务来获取天气信息并将该数据绑定到UI。返回Fahrenheit和Celcius信息,但只显示一个。
在设置页面上,用户可以选择以华氏度或摄氏度查看临时值。 用户可以随时更改此设置,并将其存储在IsolatedStorageSettings中。
我遇到的问题是: 当用户导航到“设置”页面并更改其对华氏度或Celcius的偏好时,此更改不会反映在主页面上。
这个问题让我开始在更广阔的背景下思考这个问题。我可以在任何MVVM应用程序中看到这是一个问题,其中显示取决于IsolatedStorage中的某些设置。任何时候更新IsoStore中的任何设置,ViewModels如何知道这一点?当我从NavigationSack导航回设置页面返回MainPage时,如何强制重新绑定页面?
我模型中的数据没有变化,只有我要显示的数据发生了变化。
我在这里错过了一些简单的东西吗?
提前致谢。 亚历
答案 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)
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,这是一个错误。希望这篇文章可以节省别人在这个问题上烧掉的时间。