INotifyPropertyChanged没有触发PropertyChanged

时间:2015-07-06 21:07:21

标签: c# xamarin xamarin.forms inotifypropertychanged propertychanged

我在论坛上搜索了一个解决方案,但没有一个列出的解决方案有所帮助。我假设我的实施已经关闭,但我不明白为什么或为什么。

使用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;}
    }

基本上,"之前"打印到控制台,但是" Fired"不打印。这意味着PropertyChanged为null,因此PropertyChanged没有被触发。

我错过了什么?

1 个答案:

答案 0 :(得分:2)

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

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(因为该变量将具有原始调用列表的副本)。

     

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

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

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

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