当我试图覆盖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
来解决此问题。