Creating a simple WPF application using Prism: Part 2


Here’s a link to Part 1 of this walkthrough.

Continuing where I left off, let’s look at creating the Search Module, that is going to be plugged into the “Search Region” of our shell. The UI is basically a search bar where the user can enter a membership number to search for. Begin by creating a new WPF User Control Library into your solution.

Search_Module

There are many GUI patterns you can use to compose your UI, but I’ve decided to go for the Model-View-ViewModel approach, mainly because I’ve never done used it and it will be a good exercise. As depicted by Prism guidance, we will make use of Dependency Injection and Inversion of Control with the Unity Application Block. You will require Interfaces or Base Classes with your ViewModels and Views, and at all times we will be using only Interfaces in our constructor parameters. What’s good about this approach is that you can easily inject mock objects into the class you want to unit test, because we are programming to the interface, not the implementation.

View

VS_SearchFor our search module, I’ve created a SearchView.xaml and SearchViewModel.cs with interfaces. Search.xaml.cs will look like this.

public partial class SearchView : UserControl, ISearchView
{
 public SearchView(ISearchViewModel viewModel)
 {
 InitializeComponent();
 this.DataContext = viewModel;
 }
}

The View is getting a reference to the ViewModel Interface in it’s constructor, and directly binding it to it’s DataContext. I fee that the single most powerful aspect of MVVM is the use of Xaml DataBinding to properties on the ViewModel. Added with the support of the commanding system in WPF, the MVVM pattern truly becomes a gem.

ViewModel
Next, let’s look at the code for our SearchViewModel.cs.

public class SearchViewModel : INotifyPropertyChanged, ISearchViewModel
{
    private IEventAggregator _eventAggregator;

    public SearchViewModel(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
        SearchCommand = new DelegateCommand<string>(Execute, CanExecute);
    }

    public ICommand SearchCommand { get; private set; } 

    public string _searchText;

    public string SearchText
    {
        get { return _searchText; }
        set
        {
            _searchText = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("SearchText"));
            ((DelegateCommand</string><string>)SearchCommand).RaiseCanExecuteChanged();
        }
    }

    private bool CanExecute(string text)
    {
        return !string.IsNullOrEmpty(text);
    }

    private void Execute(string text)
    {
        _eventAggregator.GetEvent<searchevent>().Publish(text);
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

As discussed, the view will be databinded to the SearchText and SearchCommand properties. IEventAggregator is used for publishing and subscribing events that are of interest, and allows for communication between modules, which we will see in the next post. Here’s a snippet of the Xaml code for databinding these properties.

<textbox x:Name="tbSearch" Width="200" Margin="10,0,0,0" Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" />
<button Content="Search" Padding="10,0,10,0" Margin="10,0,10,0"
        Command="{Binding SearchCommand}"
        CommandParameter="{Binding SearchText}" />

Module
Last of all, we look at how we tie all these together using Unity App Block. We start by creating a Module called SearchModule.cs class which inherit from IModule, and the code looks like this.

public class SearchModule : Microsoft.Practices.Composite.Modularity.IModule
{
    private Microsoft.Practices.Composite.Regions.IRegionManager _regionManager;
    private Microsoft.Practices.Unity.IUnityContainer _unityContainer;

    public SearchModule(IRegionManager regionManager, IUnityContainer unityContainer)
    {
        _unityContainer = unityContainer;
        _regionManager = regionManager;
    }

    #region IModule Members

    public void Initialize()
    {
        _unityContainer.RegisterType<isearchviewmodel , SearchViewModel>();
        _unityContainer.RegisterType<isearchview , SearchView>();
        _regionManager.RegisterViewWithRegion(RegionNames.SearchRegion, typeof(ISearchView));
    }

    #endregion
}

So far you have seen IRegionManager, IUnityContainer and IEventAggregator interfaces being used freely in the code. These are part of the Prism framework, and they get dependency injected without developer intervention. If you specify these interfaces in your class constructors, they will get injected automatically.

What’s important in the SearchModule (Of IModule) is in it’s Initialize method, where we are registering our interfaces with it’s implementation, e.g. register ISearchView to a SearchView. By registering it with Unity, they can be resolved at runtime. Last, we need to register our View with the appropriate Region. In this case we want to register the SearchView with the “SearchRegion” of our shell, which is depicted in Line 18 of the code snippet using the RegionManager class.

In order for your shell to make use of this new modular library , you need to add it to the ModuleCatalog. If you remember the BootStrapper class from Part 1 of this walkthrough, we need to add this new search module to the ModuleCatalog, so that it can be initialized during application start, like so.

protected override Microsoft.Practices.Composite.Modularity.IModuleCatalog GetModuleCatalog()
{
    ModuleCatalog catalog = new ModuleCatalog();
    catalog.AddModule(typeof(WpfComposite.Search.SearchModule));
    return catalog;
}

In this part, you have seen how to create a new Module and build your UI elements using a GUI pattern of your choice. In a similar fashion, you can create many more modules that are pluggable into your shell. The mechanism of initializing your module is via the Initialize method of your Module (Of IModule) class and hooking it up to the shell via the BootStrapper class.

In my next and last post, I will talk about how to mesh up all your communications between your modules via the Event Aggregator. Til then, enjoy…

Share this post:

Advertisements
Posted in WPF. Tags: . 1 Comment »

One Response to “Creating a simple WPF application using Prism: Part 2”

  1. Creating a simple WPF application using Prism: Part 3 « Code Blitz Says:

    […] Creating a simple WPF application using Prism: Part 2 […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: