MVVM:OnBindingContextChange:PropertyChanged 未在新 View 模型中触发

标签 mvvm xamarin.forms viewmodel

我正在编写一个 Xamarin 应用程序并尽我所能遵守 MVVM,我真的很喜欢

我通常有 ContentPages 包含对 View 的引用。

我将绑定(bind)上下文设置为页面中的 VM,然后在 View 中使用 OnBindingContextChanged

这允许我使用 PropertyChanged 方法来响应我的 View 的显示逻辑条件

我已经成功使用了几次,但我很困惑为什么额外的实现不起作用

页面看起来像这样

public partial class BindingTextPage : ContentPage
{
    public BindingTextPage()
    {
        InitializeComponent();

        this.BindingContext = new ViewModels.LocationsViewModel();
    }
}

View 看起来像这样

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

View 模型的提取,在这种情况下非常简单地设置一个字符串并因此更改一个属性,我预计这会导致 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 的二传手来电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
    }
    

    关于MVVM:OnBindingContextChange:PropertyChanged 未在新 View 模型中触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59876932/

    相关文章:

    wpf - 如何在 MVVM WPF 中从子级更改父级控件?

    c# - Xamarin.Forms.Xaml.XamlParseException : Cannot assign property "IsVisable" : Property does not exists

    c# - Tizen .NET 流播放器

    wpf - 如何使 View 模型和模型的集合保持同步

    android - ViewModelProviders 和 ViewModelProvider 类有什么区别?

    c# - 双击 ListView 时执行命令。 (WPF-MVVM)

    c# - 在泛型集合的泛型方法上使用表达式lambda

    android - BindingAdapter 未按预期工作

    Xamarin Forms - 从模式返回对象

    java - 我可以使用针对两个 Activity 观察到的 View 模型吗?