MVVM:OnBindingContextChange:PropertyChanged 未在新视图模型中触发
MVVM: OnBindingContextChange: PropertyChanged not firing in new view model
我正在编写一个 Xamarin 应用程序并尽最大努力遵守我真正喜欢的 MVVM
我通常有包含对视图的引用的 ContentPages。
我在页面中将绑定上下文设置为 VM,然后在视图中使用 OnBindingContextChanged
这允许我使用 PropertyChanged 方法来响应我的视图的显示逻辑条件
我已经成功使用了好几次,但我很困惑为什么额外的实现不起作用
页面看起来像这样
public partial class BindingTextPage : ContentPage
{
public BindingTextPage()
{
InitializeComponent();
this.BindingContext = new ViewModels.LocationsViewModel();
}
}
视图看起来像这样
private LocationsViewModel_vm;
public BindingTestView()
{
InitializeComponent();
System.Diagnostics.Debug.WriteLine("Debug: Initialised BindingTesView view");
}
protected override void OnBindingContextChanged()
{
System.Diagnostics.Debug.WriteLine("Debug: BindingTest: OnBindingContextChanged: Context " + this.BindingContext.GetType());
_vm = BindingContext as LocationsViewModel;
_vm.PropertyChanged += _vm_PropertyChanged;
}
private void _vm_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
try
{
System.Diagnostics.Debug.WriteLine("Debug: BindingTest: Method called");
System.Diagnostics.Debug.WriteLine("Debug: BindingTest: Property " + e.PropertyName);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Debug: BindingTestView: Error changing context " + ex.Message);
}
}
视图模型的提取,在这种情况下非常简单地设置一个字符串并因此更改 属性,我预计这会导致 PropertyChange 触发?
public LocationsViewModel()
{
tempMessage = "this is from the view model";
}
public string tempMessage
{
get
{
return _tempMessage;
}
set
{
_tempMessage = value;
OnPropertyChanged(nameof(tempMessage));
}
}
启动时我的调试语句显示正在调用 OnBindingContextChange,但在这个实例中 _vm_PropertyChanged 从未触发?我希望 tempMessage 设置为这样做吗?
您代码中的事件顺序如下
LocationsViewModel
的构造函数被调用
- 从您的构造函数中,您正在设置
tempMessage
tempMessage
的setter调用OnPropertyChanged
,由于事件是null
,所以没有触发
- 剩下
LocationsViewModel
的构造函数
Page.BindingContext
已设置
OnBindingContextChanged
被称为
LocationsViewModel.PropertyChanged
已被您的页面订阅
由于在您的页面订阅之前引发(或尝试引发)事件,您的页面根本不会收到有关引发事件的通知。如果在订阅事件后设置值,将按预期调用处理程序。
例如
protected override void OnBindingContextChanged()
{
_vm = BindingContext as LocationsViewModel;
_vm.PropertyChanged += _vm_PropertyChanged;
_vm.tempMessage = "Hello, world!"; // clichée , I know
}
我正在编写一个 Xamarin 应用程序并尽最大努力遵守我真正喜欢的 MVVM
我通常有包含对视图的引用的 ContentPages。
我在页面中将绑定上下文设置为 VM,然后在视图中使用 OnBindingContextChanged
这允许我使用 PropertyChanged 方法来响应我的视图的显示逻辑条件
我已经成功使用了好几次,但我很困惑为什么额外的实现不起作用
页面看起来像这样
public partial class BindingTextPage : ContentPage
{
public BindingTextPage()
{
InitializeComponent();
this.BindingContext = new ViewModels.LocationsViewModel();
}
}
视图看起来像这样
private LocationsViewModel_vm;
public BindingTestView()
{
InitializeComponent();
System.Diagnostics.Debug.WriteLine("Debug: Initialised BindingTesView view");
}
protected override void OnBindingContextChanged()
{
System.Diagnostics.Debug.WriteLine("Debug: BindingTest: OnBindingContextChanged: Context " + this.BindingContext.GetType());
_vm = BindingContext as LocationsViewModel;
_vm.PropertyChanged += _vm_PropertyChanged;
}
private void _vm_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
try
{
System.Diagnostics.Debug.WriteLine("Debug: BindingTest: Method called");
System.Diagnostics.Debug.WriteLine("Debug: BindingTest: Property " + e.PropertyName);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Debug: BindingTestView: Error changing context " + ex.Message);
}
}
视图模型的提取,在这种情况下非常简单地设置一个字符串并因此更改 属性,我预计这会导致 PropertyChange 触发?
public LocationsViewModel()
{
tempMessage = "this is from the view model";
}
public string tempMessage
{
get
{
return _tempMessage;
}
set
{
_tempMessage = value;
OnPropertyChanged(nameof(tempMessage));
}
}
启动时我的调试语句显示正在调用 OnBindingContextChange,但在这个实例中 _vm_PropertyChanged 从未触发?我希望 tempMessage 设置为这样做吗?
您代码中的事件顺序如下
LocationsViewModel
的构造函数被调用- 从您的构造函数中,您正在设置
tempMessage
tempMessage
的setter调用OnPropertyChanged
,由于事件是null
,所以没有触发- 剩下
LocationsViewModel
的构造函数 Page.BindingContext
已设置OnBindingContextChanged
被称为LocationsViewModel.PropertyChanged
已被您的页面订阅
由于在您的页面订阅之前引发(或尝试引发)事件,您的页面根本不会收到有关引发事件的通知。如果在订阅事件后设置值,将按预期调用处理程序。
例如
protected override void OnBindingContextChanged()
{
_vm = BindingContext as LocationsViewModel;
_vm.PropertyChanged += _vm_PropertyChanged;
_vm.tempMessage = "Hello, world!"; // clichée , I know
}