【问题标题】:INotifyPropertyChanged not firing PropertyChangedINotifyPropertyChanged 未触发 PropertyChanged
【发布时间】:2015-09-24 04:16:42
【问题描述】:

我已在论坛中搜索解决方案,但列出的解决方案都没有帮助。我假设我的实现已关闭,但我不明白是什么或为什么。

使用 Xamarin 表单,我试图在对象的数据发生更改时获取要更新的标签。

相关代码:

public new event PropertyChangedEventHandler PropertyChanged;

protected new virtual void OnPropertyChanged(string propertyName)
{
    System.Diagnostics.Debug.WriteLine ("Before");
    if (PropertyChanged != null)
    {
        System.Diagnostics.Debug.WriteLine ("Fired");
        PropertyChanged(this,
            new PropertyChangedEventArgs(propertyName));
    }
}

public string String {
    set { 
        if (_data == value)
            return;
        _data = value;
    OnPropertyChanged ( "String" ); }

    get { return _data; }
}

public new View Content {
        get { 
            label = new Label { Text = String };
            label.SetBinding( Label.TextProperty, new Binding( "String" ) );
            return label;}
    }

基本上,“Before”会打印到控制台,但“Fired”不会打印。这意味着 PropertyChanged 为空,因此 PropertyChanged 没有被触发。

我错过了什么?

【问题讨论】:

  • String 是一个关键字,可能会导致一些问题,您可以将其更改为“数据”吗?此外,您是否在页面上设置了绑定上下文?
  • 您正在创建绑定但没有设置 BindingContext(至少它不在您发布的代码示例中)
  • Content 属性中的 SetBinding 与设置绑定上下文不同吗?

标签: c# xamarin xamarin.forms inotifypropertychanged propertychanged


【解决方案1】:

我不知道这是否会影响它(可能不会),但我会将您的属性更改方法重写为以下内容。

protected new virtual void OnPropertyChanged(string propertyName)
{
    System.Diagnostics.Debug.WriteLine ("Before");
    var handler = this.PropertyChanged;
    if (handler == null)
    {
        return;
    }

    System.Diagnostics.Debug.WriteLine ("Fired");
    handler(this,
        new PropertyChangedEventArgs(propertyName));
}

获取事件的本地引用将保护您在多线程环境中。即使您不编写多线程代码,这也是最佳实践。在处理事件时,这是一种更安全的方法。

请参阅 Stackoverflow 上的 this answer 了解它。

对局部变量的赋值确保如果事件在 if 和实际调用之间被取消注册,则调用列表不会为空(因为变量将具有原始调用列表的副本)。

这很容易发生在多线程代码中,在检查 null 和触发事件之间,它可能被另一个线程取消注册。

接下来,我会将属性从 String 重命名为其他名称。我相信 Xamarin 的 .NET 框架实现包括 BCL 类型字符串。您可能会混淆绑定引擎,尽管它应该足够聪明以识别差异。

另外,请确保Binding 成员的方向设置为Two-Way,并且它的更新更改通知设置为PropertyChanged。这将确保在更改属性值时始终触发 OnPropertyChanged 方法。

new Binding("String")
{
    Mode = BindingMode.TwoWay,
    UpdateSourceTrigger = UpdateSourceTrigger.Explicit,
}

【讨论】:

  • 感谢您的评论。我切换到那些最佳实践。遗憾的是,就功能而言,它没有帮助。 PropertyChange 仍未启动。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-17
  • 1970-01-01
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 2021-11-27
相关资源
最近更新 更多