Prism 4: Defining Custom Command Behavior for ListBox control in Silverlight 4.0
Posted by: Mahesh Sabnis
in Category Silverlight 2, 3, 4 and 5
Abstract: In this article, I have explained how to define custom command behavior to the List Box control using Silverlight and Prism 4
Prism 4 is an excellent pattern provided to us for developing Line-of-Business (LOB) enterprise applications using Silverlight 4.0 as well as WPF 4.0. Implementing XAML only development is an excellent feature where the code-behind can be completely reduced or removed. In a typical MVVM architecture, to process the data which is send by the UI (by the ViewModel), we have been provided with an excellent Commanding concept. Command is an object which implements an ICommand interface. This provides conditional execution to the request initiated by the end-user on the SL/WPF UI and processes it using Command object defined in View-Model. I have already explained this process in my article Line of Business (LOB) Application using Silverlight 4, WCF 4, EF 4 and Commanding Architecture. The facility for commanding is provided in Prism 4 using DelegateCommand and CompositCommand objects. If you want to learn more, I have already covered it in my previous article Loosely Coupled Silverlight 4 applications using Prism 4 and Commanding
In Silverlight and WPF, commanding is available for the XAML elements like Button and MenuItem. In this case, ‘Command’ property of the Button suppress the ‘Click’ event of the Button. But when an enterprise application needs to be developed, then UI interaction operations are not only limited to these controls. Most of the times we need to provide code-less UI interaction facilities for controls like ListBox, ComboBox for Master-details operations or in some cases, we even need to provide code-less direct UI interaction facilities for DataGrid controls. But the problem with these controls is that they do not have ‘Command’ property. So the question arises - can we define a Custom Command or Command Parameter behavior to these controls? The answer is YES! In this article, I have explained the same and demonstrated it using the ListBox control. You can do the same for other controls too. You need to have VS2010, Silverlight 4.0 and Prism 4 installed on the development machine.
Step 1: Open VS 2010 and create a Silverlight 4 application, name it as ‘SL4_CustomCommands’. In this project, add the following references of the Prism 4 libraries.
You need to also add a reference to System.Core, because in this article I have used LINQ.
Step 2: In this project, add a new class file and name it ‘DataClasses.cs’. This time we define data-classes for the application.
Step 3: In the project, add a new class file and name it as ListBoxCustomCommand.cs. This file will be used to define custom behavior class for the ListBox. Add a class in the file of the name ‘ListBoxSelectionChangedCommandBehavior’. I have given this name to the class because in the ‘SelectionChanged’ event of the ListBox, I want to suppress the Custom Command property. This class is inherited from ‘CommandBehavior<ListBox>’ class. This is a generic class provided by the Prism 4 framework using which custom behavior can be provided to the Control under ‘System.Windows.Controls.Control’ family. In the constructor of this class, you need to add the following code:
Step 4: Now we need to define the Command property, CommandParameter property and the ClickCommandBehavior property for the class defined above. So in the same class file, add a new class of the name ‘ListBoxSelectionChanged’ and add the attached properties for commanding, command parameter and click behavior. (Note:use ‘propa’ TAB-TAB in VS2010, to add attached properties). The class is as shown below:
The above class defines attached properties and also defines the following methods:
GetOrCreateListBoxBehavior - This method detects the Click action for the SelectionChanged on the ListBox and returns the ClickBehavior on the control.
OnSetCustomCommandCallBack - This method return the Command object based upon the Behavior.
OnSetCustomCommandParameterCallBack - This detects the Command Parameter for the custom command for the element, that is based upon the action taken by the user on the control. In this case, the command parameter will be the ‘SelectedItem’ property of the ListBox. This parameter is further used for processing on the ViewModel.
Step 5: Now we need to build the DelegateCommand for the custom command defined above. In the project add a new class file and name it as ‘MyViewModelClass’. This class will call methods from the DataClasses defined in Step 2 and provide command objects to the UI. The code is as shown below:
The above class declares DelegateCommand objects for Loading Employees in the ListBox and Filtering Employee based upon EmpNo.
Step 6: Open MainPage.xaml and write the XAML code. In the XAML code, define the Current Application’s namespace using xmlns, define an instance of the MyViewModel class in Resources and define DataTemplate for displaying data in the ListBox. The most important part in this XAML is use of the Custom Binding properties for the ListBox. These properties can be set as shown below:
Note here that srcData:ListBoxSelectionChanged.Command is bound with the FilterEmployeeCommand, the DelegateCommand defined in MyViewModel class and srcData:ListBoxSelectionChanged.CommandParameter is bound with the ‘SelectedItem’ property of the ListBox itself.
The entire XAML is as shown below:
Note: The ‘Load Employee’ is bound with the ’LoadEmployeeCommand’, DelegateCommand declared in the ViewModel class.
Step 7: Run the application and the following result will be displayed:
Click on the Load Employee button and the List will show Employee names:
How Does This Work?
Now when you select any name from the ListBox, the SelectionChanged event will be raised. This is suppressed by the Custom Command defined in the ‘ListBoxSelectionChanged’class class. This behavior will return the ‘SelectedItem’ property of the ListBox which is bound with the Custom Parameter for the ListBox. Now since the Custom Command of the ListBox is bound with the ‘FilterEmployeeCommand’, the DelegateCommand property of the MyViewModelClass, the ‘FilterEmployee’ method from the ViweModel class will be executed which will update ‘EmployeeSelected’ public property of the type ‘Employee’ class, in the ViewModel class. Since this property is bound as the DataContext of the ‘grdEmpChild’ Grid on the MainPage.xaml and all textboxes in this Grid are bound with the properties from Employee class, these textboxes will show details of the Selected Employee in the listbox. The result will be as shown below:
The Custom commanding feature gives us more control over the code-less development. This demo showed how to use the Custom Commanding, Command Parameter feature for ListBox like controls using Prism 4. But this may not be the only requirement in enterprise application. In Prism 4, similar master details operation can also be possible using ‘IEventAggregator’ which I have explained here Silverlight and Prism: Communication between two Views of the same Module using IEventAggregator
The entire source code of this article can be downloaded over here