【问题标题】:Tabbed Page Behavior causes app crash in Xamarin.Forms选项卡式页面行为导致 Xamarin.Forms 中的应用程序崩溃
【发布时间】:2017-04-30 03:46:42
【问题描述】:

我正在尝试实现一个事件来命令行为(如 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 上,应用只是在启动时挂起,从不显示选项卡式页面。

MyTabbedPage.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 部分中的行为条目,则应用程序在两个平台上都可以正常运行。

谁能解释一下我可能做错了什么?

【问题讨论】:

  • 我发布了一个示例应用程序来演示问题up on github。我将添加分支以尝试不同的答案。谢谢大家的帮助!

标签: xaml xamarin xamarin.forms prism


【解决方案1】:

我相信您可能需要更改 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)

【讨论】:

  • 非常感谢您的帮助,@jgoldberger!看起来你让我克服了最初的最大障碍。通过您建议的更改,应用程序再次运行而不是在启动时崩溃,但是,由于某种原因,我的 DelegateCommand 没有被调用。我会继续调查。再次感谢你!如果你好奇的话,我已经把代码放在了 GitHub 上,有一个名为“jganswer”的分支,我在其中实现了你的建议:link
  • 好的...我找到了命令未执行的原因。我在 ViewModel 中弄乱了命名空间!
  • 已更新,现在工作代码在 github 上的 jganswer branch... 我只需要弄清楚如何从事件中获取新选择的选项卡名称,然后我会离开跑步!再次感谢您!
【解决方案2】:

如果您遵循 EventToCommandBehavior 的直接示例,我的猜测是会引发异常,因为您的命令需要与传入的类型不同的类型。没有看到您的项目或不知道您的项目'正在努力完成,很难给你一个更清晰的方向。

您可以尝试查看这个 Gist,它提供了如何在 CurrentPageChanged 上向 TabbedPage 添加行为的示例:https://gist.github.com/dansiegel/cdc81671f3610d8992d70c65c202f0a4

【讨论】:

  • 非常感谢@dan-s!那个要点看起来就像我正在寻找的那种东西。这是 Xamarin.Forms Prism 框架的未来部分吗?我不完全确定如何实现它,但我会玩弄它,看看我是否能得到这样的东西。如果您碰巧知道有人在应用程序中实际使用 MultiPageNavigationBehavior 的任何代码示例,请告诉我。谢谢!
  • @jbachelor 您可以随时查看 Prism 的 milestones。 XF 6.3 版本的里程碑之一是包含此类行为,该行为将由 NavigationService 自动附加。我应该补充一点,如果对您有帮助的话,您目前可以在 6.3 测试版的 TabbedPages 中使用 IActiveAware。
  • 谢谢,@dan-s!我去看看 6.3 预发布版和 IActiveAware。
  • 我尝试使用 IActiveAware 没有运气,我在哪里可以找到有用的示例?
猜你喜欢
  • 2017-05-28
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-19
  • 1970-01-01
相关资源
最近更新 更多