问题描述
我正在通过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在构造函数之前更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!