当我尝试覆盖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中修复了
答案 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
来解决它。