【问题标题】:Xamarin Forms BindableProperty Changed before constructorXamarin Forms BindableProperty 在构造函数之前更改
【发布时间】:2018-03-13 09:38:26
【问题描述】:

我在我的 App.xaml 中通过 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 方法时,我的 InnerLabel 为 null,导致 NullReferenceException。

我想知道这种行为是请求的 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;
    }
}

【问题讨论】:

  • 放你的自定义控制代码
  • @ZiyadGodil。我在问题中添加了一个代码示例。

标签: c# xaml binding xamarin.forms


【解决方案1】:

我曾在某个时候使用过similar issue,唯一的区别是它是在基于 XAML 的控件中遇到的。

我认为这个问题的根本原因是(当我们使用像这样的全局隐式样式时)基础构造函数试图设置该可绑定属性,而派生构造函数仍在等待轮到它,我们遇到了 null参考。

解决此问题的最简单方法是使用 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;
}

【讨论】:

  • 非常感谢!您是否知道此 Xamarin Forms 行为是否有意?
  • 我不相信这是一种预期的行为 - 但由于初始化逻辑错误,这是一个不幸的副作用。在基构造函数中初始化派生类属性违反了 C# 框架准则。 docs.microsoft.com/en-us/dotnet/standard/design-guidelines/…
猜你喜欢
  • 1970-01-01
  • 2021-12-17
  • 2018-12-26
  • 1970-01-01
  • 2019-01-19
  • 1970-01-01
  • 2020-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多