Xamarin.Forms 选项卡式页面行为导致应用程序崩溃
Tabbed Page Behavior causes app crash in Xamarin.Forms
我正在尝试实施一个事件来命令行为(如 Xamarin 所示:https://github.com/xamarin/xamarin-forms-samples/tree/master/Behaviors/EventToCommandBehavior)
一旦我尝试将 TabbedPage.Behaviors 部分添加到我的 TabbedPage.Xaml 中,应用程序将在 iOS 中启动时崩溃,但出现以下异常:
Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Application windows are expected to have a root view controller at the end of application launch
Native stack trace:
0 CoreFoundation 0x000000010b48434b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000115be221e objc_exception_throw + 48
2 CoreFoundation 0x000000010b488442 +[NSException raise:format:arguments:] + 98
3 Foundation 0x000000010c065e4d -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
4 UIKit 0x000000010ecb0619 -[UIApplication _runWithMainScene:transitionContext:completion:] + 3827
5 UIKit 0x000000010ecacf69 -[UIApplication workspaceDidEndTransaction:] + 188
6 FrontBoardServices 0x000000011890b723 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
7 FrontBoardServices 0x000000011890b59c -[FBSSerialQueue _performNext] + 189
8 FrontBoardServices 0x000000011890b925 -[FBSSerialQueue _performNextFromRunLoopSource] + 45
9 CoreFoundation 0x000000010b429311 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
10 CoreFoundation 0x000000010b40e59c __CFRunLoopDoSources0 + 556
11 CoreFoundation 0x000000010b40da86 __CFRunLoopRun + 918
12 CoreFoundation 0x000000010b40d494 CFRunLoopRunSpecific + 420
13 UIKit 0x000000010ecab7e6 -[UIApplication _run] + 434
14 UIKit 0x000000010ecb1964 UIApplicationMain + 159
15 ??? 0x000000012e4eb58c 0x0 + 5071877516
16 ??? 0x000000012e4eb1fd 0x0 + 5071876605
at at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/src/UIKit/UIApplication.cs:79
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/src/UIKit/UIApplication.cs:63
at TabDemo.iOS.Application.Main (System.String[] args) [0x00008] in /Users/Shared/git/Experiments/TabDemo/TabDemo.iOS/Main.cs:17
在 Android 上,应用程序只是在启动时挂起,从不显示选项卡式页面。
我的TabbedPage.Xaml 看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<TabbedPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
xmlns:local="clr-namespace:TabDemo.Views"
xmlns:behaviors="clr-namespace:TabDemo.Views.Behaviors"
x:Class="TabDemo.Views.MyTabbedPage">
<TabbedPage.Behaviors>
<behaviors:EventToCommandBehavior
EventName="CurrentPageChanged"
Command="{Binding OnCurrentPageChangedCommand}" />
</TabbedPage.Behaviors>
<NavigationPage
Title="Main">
<x:Arguments>
<local:MainPage />
</x:Arguments>
</NavigationPage>
<NavigationPage
Title="Second">
<x:Arguments>
<local:SecondPage />
</x:Arguments>
</NavigationPage>
</TabbedPage>
在后面的代码中设置行为会导致完全相同的问题。如果我删除 TabbedPage.Behaviors 部分中的行为条目,该应用程序在两个平台上都能正常运行。
任何人都可以阐明我可能做错了什么吗?
我相信您可能需要更改 EventToCommandBehavior 继承自的类型。打开 EventToCommandBehavior.cs 文件并更改:
public class EventToCommandBehavior : BehaviorBase<View>
至:
public class EventToCommandBehavior : BehaviorBase<VisualElement>
您还需要修改两个方法的签名:
protected override void OnAttachedTo (View bindable)
protected override void OnDetachingFrom (View bindable)
至:
protected override void OnAttachedTo(VisualElement bindable)
protected override void OnDetachingFrom(VisualElement bindable)
如果您按照 EventToCommandBehavior 的直接示例,我的猜测是抛出异常,因为您的命令需要与传入的类型不同的类型。没有看到您的项目,或者不知道你想要完成什么,很难给你一个更明确的方向。
您可以尝试查看此 Gist,它提供了一个示例,说明如何在 CurrentPageChanged 上向 TabbedPage 添加行为:https://gist.github.com/dansiegel/cdc81671f3610d8992d70c65c202f0a4
我正在尝试实施一个事件来命令行为(如 Xamarin 所示:https://github.com/xamarin/xamarin-forms-samples/tree/master/Behaviors/EventToCommandBehavior)
一旦我尝试将 TabbedPage.Behaviors 部分添加到我的 TabbedPage.Xaml 中,应用程序将在 iOS 中启动时崩溃,但出现以下异常:
Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Application windows are expected to have a root view controller at the end of application launch
Native stack trace:
0 CoreFoundation 0x000000010b48434b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000115be221e objc_exception_throw + 48
2 CoreFoundation 0x000000010b488442 +[NSException raise:format:arguments:] + 98
3 Foundation 0x000000010c065e4d -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
4 UIKit 0x000000010ecb0619 -[UIApplication _runWithMainScene:transitionContext:completion:] + 3827
5 UIKit 0x000000010ecacf69 -[UIApplication workspaceDidEndTransaction:] + 188
6 FrontBoardServices 0x000000011890b723 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
7 FrontBoardServices 0x000000011890b59c -[FBSSerialQueue _performNext] + 189
8 FrontBoardServices 0x000000011890b925 -[FBSSerialQueue _performNextFromRunLoopSource] + 45
9 CoreFoundation 0x000000010b429311 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
10 CoreFoundation 0x000000010b40e59c __CFRunLoopDoSources0 + 556
11 CoreFoundation 0x000000010b40da86 __CFRunLoopRun + 918
12 CoreFoundation 0x000000010b40d494 CFRunLoopRunSpecific + 420
13 UIKit 0x000000010ecab7e6 -[UIApplication _run] + 434
14 UIKit 0x000000010ecb1964 UIApplicationMain + 159
15 ??? 0x000000012e4eb58c 0x0 + 5071877516
16 ??? 0x000000012e4eb1fd 0x0 + 5071876605
at at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/src/UIKit/UIApplication.cs:79
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/src/UIKit/UIApplication.cs:63
at TabDemo.iOS.Application.Main (System.String[] args) [0x00008] in /Users/Shared/git/Experiments/TabDemo/TabDemo.iOS/Main.cs:17
在 Android 上,应用程序只是在启动时挂起,从不显示选项卡式页面。
我的TabbedPage.Xaml 看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<TabbedPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
xmlns:local="clr-namespace:TabDemo.Views"
xmlns:behaviors="clr-namespace:TabDemo.Views.Behaviors"
x:Class="TabDemo.Views.MyTabbedPage">
<TabbedPage.Behaviors>
<behaviors:EventToCommandBehavior
EventName="CurrentPageChanged"
Command="{Binding OnCurrentPageChangedCommand}" />
</TabbedPage.Behaviors>
<NavigationPage
Title="Main">
<x:Arguments>
<local:MainPage />
</x:Arguments>
</NavigationPage>
<NavigationPage
Title="Second">
<x:Arguments>
<local:SecondPage />
</x:Arguments>
</NavigationPage>
</TabbedPage>
在后面的代码中设置行为会导致完全相同的问题。如果我删除 TabbedPage.Behaviors 部分中的行为条目,该应用程序在两个平台上都能正常运行。
任何人都可以阐明我可能做错了什么吗?
我相信您可能需要更改 EventToCommandBehavior 继承自的类型。打开 EventToCommandBehavior.cs 文件并更改:
public class EventToCommandBehavior : BehaviorBase<View>
至:
public class EventToCommandBehavior : BehaviorBase<VisualElement>
您还需要修改两个方法的签名:
protected override void OnAttachedTo (View bindable)
protected override void OnDetachingFrom (View bindable)
至:
protected override void OnAttachedTo(VisualElement bindable)
protected override void OnDetachingFrom(VisualElement bindable)
如果您按照 EventToCommandBehavior 的直接示例,我的猜测是抛出异常,因为您的命令需要与传入的类型不同的类型。没有看到您的项目,或者不知道你想要完成什么,很难给你一个更明确的方向。
您可以尝试查看此 Gist,它提供了一个示例,说明如何在 CurrentPageChanged 上向 TabbedPage 添加行为:https://gist.github.com/dansiegel/cdc81671f3610d8992d70c65c202f0a4