Monday, February 25, 2008

This is the sixth of a series about using Workflow Foundation to control your UI Logic in a WPF application. The full table of contents:

Recap

In the first post, the complete solution was presented. I am presenting a solution to use workflow as the controller part in your MVC inspired WPF application. It is inspired on the thought that you do not need complex frameworks, because WPF already gives you great power (routed eventing, resources). So, no IOC is used, no event aggregator etcetera: it's taken care of by WPF and WF, a natural fit.
The solution is very decoupled and I feel it's a great advantage to be able to visual your control logic.
In the previous post, we talked about decoupling through commands.

This time, we will look at how to inject a controller into a subview

The InjectControllerAsDataTemplate activity

It's all very nice and dandy to have one controller manage it's mainview, but what happens if part of that mainview is different, and should be managed by a completely different controller?

Let's look at ModuleView in the BankTeller sample:

<UserControl x:Class="BankTellerViews.ModuleView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <StackPanel Orientation="Horizontal">
        <StackPanel Orientation="Vertical">
            <ContentPresenter ContentTemplate="{DynamicResource userinfo}" />
            <ContentPresenter ContentTemplate="{DynamicResource customerlist}"/>
        </StackPanel>
        <StackPanel Orientation="Vertical">
            <ContentPresenter ContentTemplate="{DynamicResource customerinfo}" />
            <ContentPresenter ContentTemplate="{DynamicResource customersummary}" />
        </StackPanel>
    </StackPanel>
</UserControl>

You can see that ModuleView really only determines the way this screen is build up, but the individual pieces are left empty.

When we open up the ModuleLogic controller, we wish to inject controllers with the same names that we used here:

image

What happens exactly? Well, you selected a controller type, through the convenient typebrowser, and set a specific resource key (in this case, we used a string: userinfo). The adapter is notified by this adapter to do something with it. It will create a datatemplate in code, and just set it as a resource (or replace, if it already exists).

This means that a deeply nested view could easily define a contentpresenter and a higher level controller could inject a controller for it.

Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):