The code for this lesson is attached at the bottom. You will also, need a modified version of the Northwind database which is available at the bottom of the Lesson intro page. (Click me)
Please be sure to modify the app.config file to point to the machine you which you setup restore the database too.
As with all the lessons, I would like to thank the following:
Telerik for making wonderful RAD controls which make our development lives a lot easier. The Demo versions of 2010 Q1 WPF controls were used and can be found at the Telerik website.
http://www.telerik.com/account/free-trials/single-trial.aspx?pid=601
All the assemblies used for the demo are contained in the SharedAssemblies folder in case you need to redefine any references.
A big thanks to Sacha Barber for Cinch, Josh Smith for all his work and RelayCommand and the others who have taken the time to post helpful work on the internet.
Also, in this lesson I introduce some custom command code I obtained from a video series by Jeff Brand of Slickthought.net. Check his WPF Comp App Series.
In this lesson we cover databinding & commands as they would be used in a Prism/MVVM application. If you aren't familiar with DataBinding or Commands, I suggest checking out some of the MSDN magazine articles or do a google search for more info. There is plenty of good info out there. I first learned about them in Matthew McDonald's C Sharp 2008 books.
In our Shell, we have a Telerik Ribbon control. This will contain all the application's menu items which we will bind commands to execute the needed functionality.
In the MVVM model, the commands are usually defined in a View's associated ViewModel. In this case, we'll be using the RelayCommand (created by Josh Smith). http://mvvmfoundation.codeplex.com/ (When we need a way to define a global command for the entire application, we can use the EventAggregator which is a part of Prism.)
In the ShellViewModel, we define the following commands:
Code:
RelayCommand _showCustomerTemplateCommand; RelayCommand _showEmployeeTemplateCommand;
Code:
public RelayCommand ShowCustomerTemplateCommand
{
get { return _showCustomerTemplateCommand ?? (_showCustomerTemplateCommand = new RelayCommand(param => ShowCustomerTemplate())); }
}
public RelayCommand ShowEmployeeTemplateCommand
{
get { return _showEmployeeTemplateCommand ?? (_showEmployeeTemplateCommand = new RelayCommand(param => ShowEmployeeTemplate())); }
}
The new RelayCommand using lamba expressions points to a private method which runs when the command is initiated. Notice the param variable. If you need to pass a parameter to the method, initiate the RelayCommand as follows:
Code:
public RelayCommand ShowEmployeeTemplateCommand
{
get { return _showEmployeeTemplateCommand ?? (_showEmployeeTemplateCommand = new RelayCommand(param => ShowEmployeeTemplate(param))); }
}
Code:
private void ShowCustomerTemplate()
{
CurrentTemplate = TemplateFactory.Instance.CustomerTemplate;
}
We have CurrentTemplate declared as a UserControl. ShellView contains a ContentControl bound to CurrentTemplate as shown here:
Code:
<ContentControl x:Name="TemplateUC" Content="{Binding CurrentTemplate}"></ContentControl>
With all of this wired up, when you click on the the Customer or Employee menuItems in the Telerik RibbonButton, the respective commands get fired and the appropriate template gets assigned to CurrentTemplate and displays either the Customer or Employee Views of their respective modules.
One thing to note in the ShowEmployeeTemplate() method, we make a call to load the EmployeeModule because it was set to load on demand in our bootstrapper.
Code:
private void ShowEmployeeTemplate()
{
CurrentTemplate = TemplateFactory.Instance.EmployeeTemplate;
_moduleManager.LoadModule("EmployeeModule");
}
Working with the CustomerView, in the CustomerViewModel we create an ObservableCollection<CustomerModel> named CustomerModels. We use ObservableCollection because of it's implemenation of INotifyPropertyChanged which we need so any bound elements are notified of any changes and updated automatically.
We make a call to a method to populate CustomerModels in the constructor.
We also create a SelectedCustomerCommand which is used by our Telerik Combo element. (As a side item, make note of how easy it is to define a DataTemplate to display custom data as is done with CustomerCmbTemplate. In this sample, we display the Customer Name and Phone number in the Telerik Combo.)
Also, one thing to point out is not all UI Elements natively support commands. As a work around for this, you will find a class called CommandBehavior located in the NSVMVVM assembly that contains code to allow Non-Command UI Elements to use commands. I obtained the code for CommandBehavior from a Jeff Brand sample. Jeff has put together a video walk through to explain this functionality.
Custom Commands and Non-Command UI Elements
The code for our Telerik ComboBox is as follows:
Code:
<telerik:RadComboBox MinWidth="150" Name="RCmbCustomers" IsTextSearchEnabled="True"
nsvmvvm:CommandBehavior.TheCommandToRun="{Binding Path=SelectedCustomerCommand}"
nsvmvvm:CommandBehavior.CommandParameter="{Binding ElementName=RCmbCustomers, Path=SelectedItem}"
nsvmvvm:CommandBehavior.RoutedEventName="SelectionChanged"
ItemsSource="{Binding Source={StaticResource CustomerModels}}"
ItemTemplate="{StaticResource CustomerCmbTemplate}"
SelectedValuePath="Id.DataValue"
telerik:TextSearch.TextPath="CompanyName.DataValue"
/>
We bind our Command Parameters to the SelectedItem property of our Telerik ComboBox. If you recall, with RelayCommand we have a way of passing a param. If we do, SelectedItem will get passed to the method which runs when SelectedCustomerCommand is ran.
The routedevent we subscribe to which will execute our SelectedCustomerCommand is SelectionChanged.
Thus, when a user changes the selected customer, the SelectedCustomerCommand will execute. This will in turn set our CurrentCustomerModel to the SelectedItem passed in by the command.
Next, we make a call to the IOrderController.SetCurrentOrder() method, telling the method that we need to load orders for a Customer and we pass in the CustomerId which is used to return orders for the specified customer.
The following code in the CustomerViewModel is where this takes place.
Code:
private void SelectedCustomer(Object param)
{
CurrentCustomerModel = (CustomerModel)param;
_orderController.SetCurrentOrder(new OrderType { Type = OrderTypes.Customer, Id = CurrentCustomerModel.Id.DataValue.ToString() });
}
If you look at the IOrderController.SetCurrentOrder() method, you find it calls OrderService.GetOrderModels().
OrderService.GetOrderModels() will return the orders we need to populate a public property called OrderModels.
In the OrderView we have a Telerik GridView which binds to the OrderModels collection contained in the OrderViewModel and is used to display the order info we choose to show about an order.
If you look in the Employee & Customer View, you'll see that all the UI Elements (Mostly TextBoxes) to display the related info is bound to these properties. In order to keep this lesson at a manageable length, I'm leaving out all the details. However, if you look at the databinding concepts discussed in this lesson, it should be easy to follow. If not, and you feel there needs to be more detail provided, please let me know and I'll address it.
That concludes this lessons. Our next lesson will cover the Model & Validation. As always, if you have questions please let me know.







Section Widget
Categories Widget (top-down)


Rate this article