我正在努力处理mvvm数据绑定。我没有为mvvm使用任何框架,我为视图模型提供了一个非常基本的基类。我将遇到问题的example-app上传到GitHub,找到下面的链接。
我的问题:
我有一个带有标签菜单的简单应用。有2个标签,分别为“ TabA”和“ TabB”。两种视图都有一个简单的视图模型。视图模型引用保存数据的管理器类。 Manager类必须在可观察的集合中包含对象(我的数据模型类的对象,该对象仅包含一个字符串并实现INotifyPropertyChanged)。 Manager中还有一个属性,它引用当前选择的对象(它只是列表中2个对象之一)。
“ TabB”可以执行2个动作。第一个按预期工作。如果您在条目中输入一些新字符串,然后单击第一个按钮,它将更新当前所选对象的字符串并更新TabA中的标签。
什么不起作用?使用“ TabB”类中的第二个Button,可以在Manager中切换当前所选对象的值。在调试器中,我可以看到该值已更改,但是“ TabA”中的Label无法识别它必须更新该值。
你能帮我吗?
https://github.com/dercdev/MVVM-Xamarin
在杰森(Jason)的帮助下,我来到了这样的地方:
在我的TabAViewModel中,我订阅了Manager的事件:
public TabAViewModel()
{
_mgr = Manager.Instance;
_mgr.PropertyChanged += new PropertyChangedEventHandler(obj_PropertyChanged);
}
然后我举起活动:
private void obj_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged("CurrentData");
}
更新视图的标签。
这样还可以吗?
答案 0 :(得分:1)
据我所知,更好的方法是使用INotifyPropertyChanged。如果要实现Notify,我认为您需要实现INotifyPropertyChanged接口,则可以创建一个继承了INotifyPropertyChanged的类名ViewModelBase,如下所示:
public class ViewModelBase:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
然后,您可以调用RaisePropertyChanged方法在属性更改时进行初始化,
private string _text;
public string Text
{
get
{
return _text;
}
set
{
_text = value;
RaisePropertyChanged("Text");
}
}
ObservableCollection实现INotifyPropertyChanged,从而允许集合在集合的内容发生更改时(尤其是在集合中进行了哪些更改)通知用户。例如,如果您将一个项目添加到集合,则将引发CollectionChanged事件,该事件具有告诉您新项目的索引以及将该项目包括在列表中的属性。 因此ObservableCollection _list无需调用RaisePropertyChanged方法。