Xamarin Forms:使用 Android 渲染器处理对象问题

Xamarin Forms : disposed object problem with an Android renderer

在 Xamarin Forms 中为页面内的框架使用 Android 渲染器,我需要在分配页面大小后更改此对象的位置。 该页面位于 Shell 的选项卡中,当我更改选项卡并返回时,我在渲染器中得到异常 'Cannot access a disposed object'。

异常发生在UpdatePos这一行:

SetY(20);

我的问题已通过以下代码重现:

页面:

public partial class TestPage : ContentPage
{
    public partial class Container : Frame
    {
        public delegate void PosChangedEvent();
        public event PosChangedEvent HandlerPosUpdated;
        public void Update()
        {
            HandlerPosUpdated?.Invoke();
        }
    }
    Container _container = null;
    public TestPage()
    {
        InitializeComponent();
        _container = new Container()
        {
            Content = new myView()
        };
        main_layout.Children.Add(_container); 
    }
    protected override void OnSizeAllocated(double width, double height)
    {
        base.OnSizeAllocated(width, height);
        _container.Update();
    }
}

渲染器:

public class ContainerRenderer : ViewRenderer<Frame, Android.Views.View>
{
    public ContainerRenderer(Context context) : base(context)
    {}
    public void UpdatePos()
    {
        SetY(20); // System.ObjectDisposedException: 'Cannot access a disposed object. Object name: 'ContainerRenderer'.'

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

        if (e.NewElement != null)
        {
            TestPage.Container view = e.NewElement as TestPage.Container;
            if (view != null)
            {
                view.HandlerPosUpdated += UpdatePos;
            }
        }
        if (e.OldElement != null)
        {
            TestPage.Container view = e.OldElement as TestPage.Container;
            if (view != null)
            {
                view.HandlerPosUpdated -= UpdatePos;
            }
        }
    }
}

如何避免这种异常?

欢迎任何提示!

在处理自定义渲染器时删除该处理程序:

private bool disposedValue;

protected override void Dispose(bool disposing)
{
    if (!disposedValue)
    {
        if (disposing)
        {
            RemoveHandlerPosUpdated();
        }

        disposedValue = true;
    }

    base.Dispose(disposing);
}

private void RemoveHandlerPosUpdated()
{
    if (Element != null)
    {
        TestPage.Container view = Element as TestPage.Container;
        if (view != null)
        {
            view.HandlerPosUpdated -= UpdatePos;
        }
    }

}

如果这不能解决问题,则可能需要在 TestPage.Container class 中执行一些操作,以删除附加到 HandlerPosUpdated 的任何处理程序。详情待定。