简体   繁体   English

在WP7 UserControl中使用Caliburn会引发异常

[英]Using Caliburn in a WP7 UserControl throws exception

I'm trying to build a UserControl for a Windows Phone app using Caliburn Micro inside the control. 我正在尝试使用控件内部的Caliburn Micro为Windows Phone应用程序构建UserControl。 The bootstrapper is usually setup in the App resources 引导程序通常是在应用程序资源中设置的

  <Application.Resources>
     <local:AppBootstrapper x:Key="bootstrapper" />
  </Application.Resources>

I try to do this in the Xaml of the user control. 我尝试在用户控件的Xaml中执行此操作。

 <UserControl.Resources>
     <local:AppBootstrapper x:Key="bootstrapper" />
 </UserControl.Resources>

But this throws an exception during initialization when the component is loaded. 但这会在初始化期间在加载组件时引发异常。 The LoadComponent call throws the exception: "A first chance exception of type 'System.InvalidOperationException' occurred in Microsoft.Phone.ni.dll" LoadComponent调用引发异常:“ Microsoft.Phone.ni.dll中发生了'System.InvalidOperationException'类型的第一次机会异常”

Where and when should the bootstrapper be initialised? 引导程序应在何时何地初始化?

It's not intended to be used in a UserControl's resources, so I can't guarantee any good or bad behavior. 它不打算在UserControl的资源中使用,所以我不能保证任何良好或不良的行为。 The bootstrapper should be used in the application resources or you can instantiate it directly in code. 引导程序应在应用程序资源中使用,也可以直接在代码中实例化。 Try creating it in the user control's ctor, just after the InitializeComponent call. 尝试在InitializeComponent调用之后在用户控件的ctor中创建它。

Since you are placing a bootstrapper on a UserControl it seems that the PhoneApplicationService is probably already instantiated - have you tried putting the boostrapper in the app resources section? 由于您在用户控件上放置了引导程序,因此似乎PhoneApplicationService可能已被实例化-您是否尝试过将boostrapper放在应用程序资源部分中?

The CM source shows that CM creates a new instance of PhoneApplicationService when the bootstrapper initialises and that looks like the issue, the root of your application must have already created an instance. CM源显示启动程序初始化时CM创建了PhoneApplicationService的新实例,并且看起来像问题一样,您的应用程序的根必须已经创建了一个实例。

Is there a reason you can't use the boostrapper in the standard way (in app resources)? 您是否有理由不能(在应用程序资源中)以标准方式使用boostrapper? Does your App.xaml contain an initialiser for PhoneApplicationService ? 您的App.xaml是否包含PhoneApplicationService的初始化程序?

Edit: 编辑:

CM source where you are getting the error is in PrepareApplication . 出现错误的CM源在PrepareApplication eg 例如

protected override void PrepareApplication() {
        base.PrepareApplication();

            phoneService = new PhoneApplicationService();
            phoneService.Activated += OnActivate;
            phoneService.Deactivated += OnDeactivate;
            phoneService.Launching += OnLaunch;
            phoneService.Closing += OnClose;

            Application.ApplicationLifetimeObjects.Add(phoneService);

            if (phoneApplicationInitialized) {
                return;
            }

            RootFrame = CreatePhoneApplicationFrame();
            RootFrame.Navigated += OnNavigated;

            phoneApplicationInitialized = true;
        }

You could probably just subclass this and get away with not creating a new PhoneApplicationService but reusing the existing one: 您可能只是将其子类化,而不必创建新的PhoneApplicationService而是重新使用现有的:

    /// <summary>
    /// A custom bootstrapper designed to setup phone applications.
    /// </summary>
    public class CustomPhoneBootstrapper : Bootstrapper {
    bool phoneApplicationInitialized;
    PhoneApplicationService phoneService;

    /// <summary>
    /// The root frame used for navigation.
    /// </summary>
    public PhoneApplicationFrame RootFrame { get; private set; }

    /// <summary>
    /// Provides an opportunity to hook into the application object.
    /// </summary>
    protected override void PrepareApplication(PhoneApplicationService phoneAppService, PhoneApplicationFrame rootFrame) {
        base.PrepareApplication();

        phoneService = phoneAppService;
        phoneService.Activated += OnActivate;
        phoneService.Deactivated += OnDeactivate;
        phoneService.Launching += OnLaunch;
        phoneService.Closing += OnClose;

        Application.ApplicationLifetimeObjects.Add(phoneService);

        if (phoneApplicationInitialized) {
            return;
        }

        RootFrame = rootFrame;
        RootFrame.Navigated += OnNavigated;

        phoneApplicationInitialized = true;
    }

    void OnNavigated(object sender, NavigationEventArgs e) {
        if (Application.RootVisual != RootFrame) {
            Application.RootVisual = RootFrame;
        }
    }

    /// <summary>
    /// Occurs when a fresh instance of the application is launching.
    /// </summary>
    protected virtual void OnLaunch(object sender, LaunchingEventArgs e) { }

    /// <summary>
    /// Occurs when a previously tombstoned or paused application is resurrected/resumed.
    /// </summary>
    protected virtual void OnActivate(object sender, ActivatedEventArgs e) { }

    /// <summary>
    /// Occurs when the application is being tombstoned or paused.
    /// </summary>
    protected virtual void OnDeactivate(object sender, DeactivatedEventArgs e) { }

    /// <summary>
    /// Occurs when the application is closing.
    /// </summary>
    protected virtual void OnClose(object sender, ClosingEventArgs e) { }
}

Disclaimer: Not sure if any of this will work since I've never devved for Windows Phone but as far as I can see that should do what the original bootstrapper did but skip the creation of the application and the root frame. 免责声明:由于我从未为Windows Phone开发过软件,因此不确定是否可以使用,但据我所知应该执行原始引导程序所执行的操作,但跳过应用程序和根框架的创建。 You just need to supply the app and the root frame (or maybe just the app if you can get the root frame from the application object - like I said, no idea what's possible) 您只需要提供应用程序和根框架(或者,如果您可以从应用程序对象获得根框架,则可能仅提供应用程序-就像我说的那样,不知道有什么可能)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM