简体   繁体   English

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

[英]Xamarin.Forms Java.Lang.NullPointerException when ContentPage has SizeChanged event listener

I'm getting the following error message when I try to overwrite a Xamarin.Forms ContentPage.Content .当我尝试覆盖 Xamarin.Forms ContentPage.Content时收到以下错误消息。

I just get the message if the new ContentPage has a SizeChanged event listener.如果新的ContentPage具有SizeChanged事件侦听器,我只会收到消息。

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

Code of the ContentPage I want to load我要加载的 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);
        }

    }

Code from the caller of above ContentPage来自上述 ContentPage 调用者的代码

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

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

I don't get the Exception if I call ShowSizePage directly from my MainPage .如果我直接从MainPage调用ShowSizePage则不会收到异常。

What do I have to change to avoid the Exception?我必须改变什么才能避免异常?

Edit minimal reproducible example code:编辑最小的可重现示例代码:

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." };
        }
    }
}

Update: The exception occurs on Xamarin.Forms v4.4.0.991265 but seems to be fixed in v4.6.0.726更新:异常发生在 Xamarin.Forms v4.4.0.991265 上,但似乎在 v4.6.0.726 中得到修复

I found a solution to get rid of the Exception while getting the desired result.我找到了一种解决方案,可以在获得所需结果的同时摆脱异常。

I had to wrap the Page Content into a ContentView and bind the SizeChanged event to the ContentView我必须将页面内容包装到ContentView并将SizeChanged事件绑定到ContentView

Working Code Sample :工作代码示例

    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);
        }
    }

This issue has been fixed in the latest version of Xamrin.forms v4.6.0.726 .此问题已在最新版本的 Xamrin.forms v4.6.0.726 Anyone who meet this issue with earlier version can update your Xamarin.Forms to solve it.任何在早期版本中遇到此问题的人都可以更新您的Xamarin.Forms来解决它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM