离开页面时是否调用控件OnElementChanged()?

时间:2018-09-16 10:12:37

标签: c# xamarin xamarin.forms

我正在页面上使用此iOS SegmentedControlRenderer。

但是,当我以这种方式转到页面:Navigation.PushAsync(new CFSPage()),然后单击后退箭头转到上一页时,将触发我的客户iOS渲染器中的OnElementChanged事件。我的渲染器的结果是,以下行给出了空引用错误:

  

segmentedControl.TintColor = e.NewElement?.TintColor.ToUIColor();

有人可以解释一下它的目的吗?这行,也应该在if (e.NewElement != null)检查之后还是该行之后。我是否正确地说,如果没有NewElement,应执行以下几行?

segmentedControl.TintColor = e.NewElement?.TintColor.ToUIColor();
SetNativeControl(segmentedControl);
SetSelectedSegment();

此渲染器没有

protected override void Dispose(bool disposing)

是否缺少某些东西?

渲染器

public class SegmentedControlRenderer : ViewRenderer<SegmentedControl, UISegmentedControl>
{
    protected override void OnElementChanged(ElementChangedEventArgs<SegmentedControl> e)
    {
        base.OnElementChanged(e);
        UISegmentedControl segmentedControl = null;
        if (Control == null)
        {
            segmentedControl = new UISegmentedControl();
            for (var i = 0; i < e.NewElement.Children.Count; i++)
            {
             segmentedControl.InsertSegment(Element.Children[i].Text, i, false);
            }
            SetNativeControl(segmentedControl);
            SetSelectedSegment();
        }
        if (e.OldElement != null)
        {
            if (segmentedControl != null)
                segmentedControl.ValueChanged -= NativeValueChanged;
        }
        if (e.NewElement != null)
        {
            segmentedControl.ValueChanged += NativeValueChanged;
        }
        segmentedControl.TintColor = e.NewElement?.TintColor.ToUIColor();
        SetNativeControl(segmentedControl);
        SetSelectedSegment();
    }

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

        if (e.PropertyName == nameof(SegmentedControl.SelectedSegment))
            SetSelectedSegment();
        if (e.PropertyName == SegmentedControl.TintColorProperty.PropertyName)
            SetSegmentTintColor();
    }

    void NativeValueChanged(object sender, EventArgs e)
    {
        if (Element is SegmentedControl formsElement)
        {
            formsElement.SelectedSegment = (int)Control.SelectedSegment;
        };
    }

    void SetSegmentTintColor()
    {
        if (Element is SegmentedControl formsElement)
            Control.TintColor = formsElement.TintColor.ToUIColor();
    }

    void SetSelectedSegment()
    {
        if (Element is SegmentedControl formsElement)
        {
            if (formsElement.SelectedSegment >= 0 && formsElement.SelectedSegment < Control.NumberOfSegments)
                Control.SelectedSegment = formsElement.SelectedSegment;
        }
    }
}

2 个答案:

答案 0 :(得分:3)

?。可以在C# 6.0 docs处找到:

  

您需要检查变量的每次访问,以确保您不会   取消引用null。空条件运算符进行这些检查   更轻松,更流畅。

     

只需将成员访问权限.替换为?.

简而言之:

segmentedControl.TintColor = e.NewElement?.TintColor.ToUIColor();

与以下相同:

  if (e.NewElement != null)
  {
      segmentedControl.TintColor = e.NewElement.TintColor.ToUIColor();
  }

是的,您是正确的,如果有NewElement,则不应执行。

答案 1 :(得分:2)

以下是大多数渲染器中OnElementChanged的结构示例:

protected override void OnElementChanged(ElementChangedEventArgs<Type> e)
{
    base.OnElementChanged(e);

    if (e.OldElement != null)
    {
        // Unsubscribe from event handlers and cleanup any resources
    }

    if (e.NewElement != null)
    {
        if (Control == null)
        {
            // Instantiate the native control and assign it to the Control property with
            // the SetNativeControl method
        }

        // Configure the control and subscribe to event handlers
    }
}

请注意,当Control为true时,if (e.OldElement != null)可能为null,在这种情况下通常不应重新创建。

另请参阅Xamarin.Forms iOS ButtonRenderer