ContentPage具有SizeChanged事件侦听器时,Xamarin.Forms Java.Lang.NullPointerException

时间:2020-05-05 20:50:34

标签: c# xamarin xamarin.forms

当我尝试覆盖Xamarin.Forms ContentPage.Content时收到以下错误消息。

如果新的ContentPage具有SizeChanged事件监听器,我只会收到消息。

Java.Lang.NullPointerException
  Message=Attempt to read from field 'int android.view.ViewGroup$LayoutParams.width' on a null object reference

我要加载的ContentPage代码

    public class ShowSizePage : ContentPage
    {
        readonly Label label;
        public ShowSizePage()
        {
            label = new Label
            {
                FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions = LayoutOptions.Center,
                Text = "initialized",
            };

            SizeChanged += OnPageSizeChanged;
            Content = label;
        }
        void OnPageSizeChanged (object sender, EventArgs args)
        {
            label.Text = String.Format("{0} \u00D7 {1}", Width, Height);
        }

    }

ContentPage上方的调用者提供的代码

// Part of an other ContentPage
        void OnShowSizeClicked (object sender, EventArgs args)
        {
            ContentPage c = new ShowSizePage();

            Content = c.Content; // Exception is caused here
        }

如果我直接从我的ShowSizePage呼叫MainPage,我不会得到例外。

为了避免发生异常,我需要更改什么?

编辑最少的可复制示例代码:

using System;
using Xamarin.Forms;

namespace NP_Exception
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            // Change this to false to see that ShowSizePage works properly if not loaded through MenuPage
            bool showMenu = true;

            if (showMenu)
                MainPage = new MenuPage(); // Throws exception
            else
                MainPage = new ShowSizePage(); // Works
        }
    }

    public class MenuPage : ContentPage
    {
        readonly StackLayout menu = new StackLayout();
        readonly ScrollView menuView = new ScrollView();
        public MenuPage ()
        {
            Button showSizeButton = new Button { Text = "Show Size" };
            showSizeButton.Clicked += OnShowSizeClicked;
            menu.Children.Add(showSizeButton);

            Button showLabelButton = new Button { Text = "Show Label" };
            showLabelButton.Clicked += OnShowLabelClicked;
            menu.Children.Add(showLabelButton);

            menuView.Content = menu;

            Content = menuView;
        }    
        void OnShowSizeClicked(object sender, EventArgs args)
        {
            ContentPage c = new ShowSizePage();

            Content = c.Content; // Exception is caused here
        }

        void OnShowLabelClicked(object sender, EventArgs args)
        {
            ContentPage c = new ShowLabelPage();

            Content = c.Content;
        }

        protected override bool OnBackButtonPressed()
        {
            Content = menuView;

            return true;
        }
    }
    public class ShowSizePage : ContentPage
    {
        readonly Label label;
        public ShowSizePage()
        {
            label = new Label
            {
                FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions = LayoutOptions.Center,
                Text = "initialized",
            };

            SizeChanged += OnPageSizeChanged;
            Content = label;
        }
        void OnPageSizeChanged(object sender, EventArgs args)
        {
            label.Text = String.Format("{0} \u00D7 {1}", Width, Height);
        }

    }
    public class ShowLabelPage : ContentPage {
        public ShowLabelPage ()
        {
            Content = new Label { Text = "Hello World! Press hardware back button for menu." };
        }
    }
}

更新: Xamarin.Forms v4.4.0.991265发生了例外,但似乎已在v4.6.0.726中修复了

2 个答案:

答案 0 :(得分:1)

我找到了一种解决方案,可以在获得所需结果的同时摆脱Exception。

我必须将页面内容包装到ContentView中,并将SizeChanged事件绑定到ContentView

工作代码示例

    public class ShowSizePage : ContentPage
    {
        readonly Label label;
        public ShowSizePage()
        {
            label = new Label
            {
                FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
                HorizontalOptions = LayoutOptions.Center,
                VerticalOptions = LayoutOptions.Center,
                Text = "initialized",
            };

            // Wrap Content in ContentView to avoid Exception
            ContentView view = new ContentView { Content = label };

            // Bind SizeChanged event to view
            view.SizeChanged += OnPageSizeChanged;

            // Set View as Content
            Content = view;
        }
        void OnPageSizeChanged(object sender, EventArgs args)
        {
            // Use Width & Height of the sender object
            View view = (View)sender;

            label.Text = String.Format("{0} \u00D7 {1}", view.Width, view.Height);
        }
    }

答案 1 :(得分:0)

此问题已在最新版本的Xamrin.forms v4.6.0.726中得到解决。使用较早版本解决此问题的任何人都可以更新您的Xamarin.Forms来解决它。