本文介绍了Xamarin形式BindableProperty在构造函数之前更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm adding a resource through XAML in my App.xaml. This resource is a implicit style that will be assigned to a CustomControl. The CustomControl contains a label.

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

To set the TextColor of this label I create a bindable property on the CustomControl and assign a value with the implicit style. Using the PropertyChanged method of the BindableProperty I set the TextColor of the Label inside my CustomControl.

<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方法.

This used to work in XF 2.3.2.127 but when I updated to XF 2.3.4.270 I started getting a NullReferenceException in the CustomControl - BindableProperty -InnerLabelTextColorChanged method.

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

The PropertyChanged method is called before executing the constructor. My InnerLabel is null when the PropertyChanged method is executed which causes the NullReferenceException.

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

I was wondering if this behaviour is the requested XF behaviour or if it is a bug?

如果这是要求的行为,那么谁能提供正确的方法来处理这种情况?

If it is the requested behaviour, can anyone provide the correct way of handling this situation?

谢谢!

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

Edit - custom control code sample

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

推荐答案

我曾经解决过类似问题 ,唯一的不同是在基于XAML的控件中遇到了它.

I had worked on a similar issue sometime back, the only difference being it was encountered in a XAML based control.

我认为导致此问题的根本原因是(当我们使用像这样的全局隐式样式时)基本构造函数尝试设置该可绑定属性,并且由于派生构造函数仍在等待轮换,我们遇到了null参考.

I think the root cause for this problem is that (when we use an global-implicit style like that) the base constructor tries to set that bindable property, and as derived constructor is still waiting for its turn, we encounter the null reference.

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

Simplest way to resolve this would be to use Binding to set properties on inner-child controls (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;
}

这篇关于Xamarin形式BindableProperty在构造函数之前更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 09:42