我正在通过XAML在App.xaml中添加资源。此资源是隐式样式,将分配给CustomControl。 CustomControl包含一个标签。

要设置此标签的TextColor,我在CustomControl上创建一个可绑定的属性,并使用隐式样式指定一个值。使用BindableProperty的PropertyChanged方法,我在CustomControl中设置了标签的TextColor。

<Style TargetType="CustomControl" >
     <Setter Property="InnerLabelTextColor" Value="Green" />
</Style>


--

private static void InnerLabelTextColorChanged(BindableObject bindableObject, object oldValue, object newValue)
{
    ((CustomControl)bindableObject).InnerLabel.TextColor = (Color)newValue;
}


这曾经在XF 2.3.2.127中起作用,但是当我更新到XF 2.3.4.270时,我开始在CustomControl-BindableProperty-中获得NullReferenceException-
InnerLabelTextColorChanged方法。

在执行构造函数之前,将调用PropertyChanged方法。当执行PropertyChanged方法导致NullReferenceException时,我的InnerLabel为null。

我想知道此行为是请求的XF行为还是错误?

如果这是要求的行为,那么有人可以提供正确的方法来处理这种情况吗?

谢谢!

编辑-自定义控制代码示例

public sealed class CustomControl : ContentView
{
    public static readonly BindableProperty InnerLabelTextColorProperty =
        BindableProperty.Create("InnerLabelTextColor", typeof(Color), typeof(CustomControl), Color.Black,
            BindingMode.OneWay, null, CustomControl.InnerLabelTextColorChanged, null, null, null);


    public CustomControl()
    {
        this.InnerLabel = new Label();

        this.Content = this.InnerLabel;
    }


    public Label InnerLabel { get; set; }


    public Color InnerLabelTextColor
    {
        get
        {
            return (Color)this.GetValue(CustomControl.InnerLabelTextColorProperty);
        }
        set
        {
            this.SetValue(CustomControl.InnerLabelTextColorProperty, value);
        }
    }


    private static void InnerLabelTextColorChanged(BindableObject bindableObject, object oldValue, object newValue)
    {
        ((CustomControl)bindableObject).InnerLabel.TextColor = (Color)newValue;
    }
}

最佳答案

我曾经在similar issue上工作过,唯一的区别是在基于XAML的控件中遇到了它。

我认为导致此问题的根本原因是(当我们使用类似全局隐式的样式时)基本构造函数尝试设置可绑定属性,而派生构造函数仍在等待其轮换,我们遇到了空引用。

解决此问题的最简单方法是使用Binding设置内部子控件(reference)的属性:

public CustomControl()
{
    this.InnerLabel = new Label();

    // add inner binding
    this.InnerLabel.SetBinding(Label.TextColorProperty,
         new Binding(nameof(InnerLabelTextColor),
                     mode: BindingMode.OneWay,
                     source: this));

    this.Content = this.InnerLabel;
}

10-04 19:05