可绑定属性通知属性更改。

6
在我创建的自定义ContentView上,我创建了一个BindableProperty,如下所示。
public static readonly BindableProperty StrokeColorProperty = 
    BindableProperty.Create("StrokeColor", 
                            typeof(Color), 
                            typeof(SignaturePadView), 
                            Color.Black, 
                            BindingMode.TwoWay);

但是我必须在属性更改时进行通知,因为我必须在自定义渲染器中读取该属性,我该如何实现呢?
如果我将其设置在BindablePropertyPropertyChanged上,它是一个静态方法,所以我无法从那个方面获取 :(

2个回答

12

BindableProperty的PropertyChanged事件处理程序确实是静态的,但它上面的输入参数是动态绑定的。

BindingPropertyChangedDelegate<in TPropertyType>(BindableObject bindable, TPropertyType oldValue, TPropertyType newValue);

正如您所看到的,第一个输入参数将是BindableObject。您可以安全地将bindable强制转换为您的自定义类,并获取已更改属性的实例。像这样:

public static readonly BindableProperty StrokeColorProperty = 
    BindableProperty.Create("StrokeColor", 
                            typeof(Color), 
                            typeof(SignaturePadView), 
                            Color.Black, 
                            BindingMode.TwoWay,
propertyChanged: (b, o, n) =>
                {
                    var spv = (SignaturePadView)b;
                    //do something with spv
                    //o is the old value of the property
                    //n is the new value
                });

这展示了在共享代码中捕获属性更改的正确方法,其中属性已被声明。如果您在本地项目中具有自定义渲染器,则它的OnElementPropertyChanged事件触发,其中"StrokeColor"为PropertyName,无论是否提供了该propertyChanged委托给BindableProperty定义。


所以我必须这样做 var spv = bindable as SignaturePadView; spv? .OnPropertyChanged("StrokeColor")。为什么它不会自动调用呢? - Lasse Madsen
如果没有 SignaturePadView 的实例属性发生变化,那么属性更改事件如何触发?直接转换应该是非常安全和明确的意图。 - irreal
你是对的 ;) 但即使我这样称呼它,OnElementPropertyChanged也不会使用该参数名称进行调用。哦,我想通了;在BindableProperties之后,渲染器首先被更改。 - Lasse Madsen
我刚刚向您展示了如何在共享代码中正确捕获实际属性更改,您抱怨说这是不可能的,因为它是静态的。我甚至没有试图弄清楚为什么您的渲染器没有捕获它。您能否验证已正确注册渲染器并实际用于呈现自定义控件?还要验证您是否实际更改了相关属性,并且可绑定属性更改事件正在触发。 - irreal
我创建了一个小的测试程序,其中我精确地复制并粘贴了您的可绑定属性定义。然后我在 Android 项目中添加了一个自定义渲染器,并且当我更新自定义控件上的“StrokeColor”属性时,它的 OnElementPropertyChanged 事件立即触发。因此,要么您的渲染器没有设置好,要么您没有更改该属性。 - irreal
设置当前属性的新值:private static void OnChanged(BindableObject bindable, object oldvalue, object newvalue) { Device.BeginInvokeOnMainThread(() => { var control = bindable as SAIcon; if (control == null) return; control.IconBackgroundColor = (Color)newvalue; }); } - Abdullah Tahan

0

在您的渲染器上覆盖OnElementPropertyChanged方法:

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if(e.PropertyName=="StrokeColor")
            DoSomething();
    }

它从未使用那个“PropertyName”被调用。 - Lasse Madsen
我该如何获取旧值? - rraallvv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接