Screens & Conductors Documentation

Sep 16, 2010 at 4:52 AM

Rob,

I realise you've been doing a lot lately with all your checkins, but is there any chance on getting the next article surrounding screens and conductors.

I'm building a WPF app that is using nested tabcontrols whereby each tabcontrol needs to be a screen conductor that is notified and performs actions when its selected tab is switched.

I've been digging around in the code but am not really sure where to start on it. Any more guidance would be greatly appreciated.

 

P.S. Excellent framework - It's allowed us to rapidly create a fairly complex WPF application in just a couple of days.

Sep 16, 2010 at 6:36 AM

Rudi Grobler recently wrote a post on exactly that topic:

http://www.rudigrobler.net/Blog/screen-conductor-101

Sep 16, 2010 at 8:56 AM

Thanks for the link, it has helped explain where to start. I guess my issue is that I was using a TabControl that was getting bound to a dynamic collection of IScreens and each TabItem was being created dynamically for each screen as opposed to in Rudi's example where he hard-coded two named buttons in place with two known screens.

Using a tab control, I can't for the life of me work out how to monitor the switching of tabs and have actions invoked at that point along with switching to the new screen.

I tried manually binding the SelectedItem of the TabControl to a property in the ViewModel, but am not sure how to get the framework to Invoke an action with a fully wired up ActionExecutionContext with the Source set to the TabItem that was just selected.

I then tried ditching TabControls altogether and using Buttons like in Rudi's example, but am doing a lot of jumping through hurdles now to try and dynamically display buttons based on the screens that are available in the dynamic collection that I am populating.

Has anyone else had any success in using TabControls as a Conductor and performing actions when switching between screens?

Coordinator
Sep 16, 2010 at 3:11 PM

There are two things you need to get the result you want:

The first is to have the proper bindings set up on the TabControl. It should work if you simply name the control "Items" That should bind the ItemsSource to the conductors Items and the SelectedItem to the conductors's ActiveItem. It should also create the default data template in order to display views correctly. Make sure you have the latest code, because I just recently fixed a bug around WPF TabControl conventions. You can read through this: http://compiledexperience.com/blog/posts/Building-a-Visual-Studio-Style-Tabbed-Interface-with-Caliburn which discusses how to do this with Caliburn v1, but it might also help to clarify a few things.

The second thing you need to do is have a service or view model that represents the changing buttons/toolbar whatever. This should be injected into each of your screens. Then, in each screen, override OnActivate to add custom buttons and be sure to remove custom buttons in OnDeactivate. Each time the tab is selected its VM's Activate method will be called and each time it is deselected, its VM Deactivate method will be called. If you have some code you only want to execute the first time a tab is activate, but not on subsequent times, override OnInitialize. If you have code you only want to execute when the tab is closed, override OnDeactivate and check the bool parameter to determine whether the tab is being deactivated and closed. If you need to prevent closing of a tab under certain circumstances, override CanClose.

Does that help? Let me know if you have further problems. I can probably get you up an running with this pretty quick.

Sep 17, 2010 at 12:10 AM

Not to hijack this thread but it would be nice if we could have a way for people to add their blog links to the documentation list... maybe as 'External Documentation'.  I try to read every thread but it is easy to miss updates.  Obviously you don't want spam up there but it sure would help make a nice repository.

Just a thought

jack

Sep 17, 2010 at 2:47 AM

Rob,

Thanks for your reply, I'm not quite sure what you mean by have a service or view model that represents the changing buttons/toolbar. I don't have a toolbar or any other control that is changing the tabs, it is just the tabs themselves. I have uploaded a sample solution to show you what I mean: TabbedViews.zip

My app is a client/server based application (we're converting a web based solution into a rich WPF client application) whereby every action through the app hits a web service that actually does the action. It sounds terrible, but this isn't a traditional app and I won't bore you with the details as to why it does this.

Therefore the client is very thin whereby just about every button click and tab switch etc results in the exact same call to the web service each time but passing in different parameters such as the name of the button that was clicked and the view that it was on. The web service then goes away and acts on that request. In this way a tab switch is treated in exactly the same manner as clicking a button, and needs to result in the ActionLogger.Execute method being invoked.

I have implemented what you suggested in your last post, and can now handle OnActivate in the ViewModels, but am not sure how to invoke the Action from there.

Thanks for your help.