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



当我试图覆盖Xamarin.FormsContentPage.Content时,收到以下错误消息。

如果新的ContentPage有一个SizeChanged事件侦听器,我就会得到消息。

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

我要加载的内容页面的代码

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
}

如果我直接从MainPage调用ShowSizePage,则不会得到异常。

为了避免异常,我必须更改什么?

编辑最小可复制示例代码:

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出现异常。表单v4.4.0.991265,但在v4.6.0.726 中似乎已修复

我找到了一个解决方案,可以在获得所需结果的同时消除异常。

我必须将页面内容包装到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);
}
}

此问题已在最新版本的Xamrin.formsv4.6.0.726中修复。任何在早期版本中遇到此问题的人都可以更新您的Xamarin.Forms来解决此问题。

最新更新