Accessing Child Window Service from App.xaml.cs

Mar 20, 2011 at 11:47 PM

Hi,

I've recently started using Cinch V2 on a Silverlight project and I really like the simplicity of getting up and running quickly.

My first real issue I've had is this.

In my App.xaml.cs I have the followin event registration in the constructor

        public App()
        {
            this.Startup += this.Application_Startup;
            this.UnhandledException +=  this.Application_UnhandledException;

            InitializeComponent();
        }

I then have my unhandled exception event handler in which I'd like to use the ChildWindowService to show an error so I've added the following code:

            ChildWindowService.Show(ChildWindowNames.ErrorWindowName, new ErrorWindowViewModel(e.ExceptionObject), (s, args) =>
            {
                
            });

as well as the following property on the class:

        [Import]
        public IChildWindowService ChildWindowService
        {
            get;
            set;
        }

In my app startup event I had the following:

         private void Application_Startup(object sender, StartupEventArgs e)
        {
            this.RootVisual = new MainPage();
            CinchBootStrapper.Initialise(new List<Assembly> { typeof(App).Assembly });
           
        }

 This left me with an IChildWindowService that was null, so I manually forced MEF to satisfy my imports by changing my app start event handler to the following:

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            this.RootVisual = new MainPage();
            CinchBootStrapper.Initialise(new List<Assembly> { typeof(App).Assembly });
            CompositionInitializer.SatisfyImports(this);
            
        }

I now have access to the IChildWindowService, but unfortuantely the registered windows count is 0. I've imported the service elsewhere in the application (i.e. other view models) and the correct windows are registered there.

So my question is, how can I get acccess to my registered windows from within app.xaml.cs

Cheers

JT

 

 

 

 

Mar 21, 2011 at 8:03 AM

The reason you are not getting the service resolved normally is that Meffed usually uses a attached DP on the  View to resolve the ViewModel from MEF container by using contract name. No other container resolution is done in Cinch apart from via the attached DPs on the view, so what you have had to do with the 

CompositionInitializer.SatisfyImports(this);

 

That is correct, or you could also use this line to get instance of IChildWindowService manually from MEF container

IChildWindowService childWindowService =  ViewModelRepository.Instance.Resolver.Container.GetExport<IChildWindowService>().Value;

 

So that's that. Now to your other issue, once you have a valid child window service import you can add stuff manually to the service using the Register(..) method (granted you should not need to do that, but it will work until we figure your issue out). I do not know why you are not getting child windows registered, it could be due to where you are trying to use it, which is essentially in a startup method, does seem strange though. Are your child windows marked up with the correct PopupNameToViewLookupKeyMetadataAttribute attributes to get picked up by the cinch bootstrapper (see the CinchV2 Silverlight demo). That is all I can think off.

You can still add things manually to your IChildWindow service after you have an instance of it MEFed in for now. I will have to try and see what happens for me, I'll see and get back to you.

 

 



Mar 21, 2011 at 11:07 PM

Hi Sacha,

Thanks for the quick response. I decided the SatisfyImports bit just didn't feel right.

After I posted this I basically modified my App startup event to look like the following

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            this.RootVisual = new MainPage();
            CinchBootStrapper.Initialise(new List<Assembly> { typeof(App).Assembly });

            ChildWindowService = ViewModelRepository.Instance.Resolver.Container.GetExport<IChildWindowService>().Value;
            ChildWindowService.Register(ChildWindowNames.ErrorWindowName, typeof(ErrorWindow));          
        }

I'm not sure why the registration via the PopupNameToViewLookupKeyMetadataAttribute didn't work either, but like you said, given the location of this particular code I don't think it's a deal breaker.

Let me know if you discover the root cause of the problem, but if not, that's cool because at least now I have it working.

Cheers

JT

Mar 22, 2011 at 7:54 AM

That would work just fine, when I get some time I'll try and replicate your arrangement.