Monday, November 16, 2009

Commanding with PRISM in Silverlight 3

You have probably already heard about PRISM, but in case you, like me, have not really looked at it I thought I would write a small intro to using commands in PRISM.

What is PRISM ?

The Composite Client Application Guidance is designed to help you more easily build modular Windows Presentation Foundation (WPF) and Silverlight client applications. These types of applications typically feature multiple screens, rich, flexible user interaction and data visualization, and role-determined behavior. They are "built to last" and "built for change."

Source : http://www.codeplex.com/CompositeWPF/

Prism is a much broader field then just commanding, and I will spend a few future blogpost in explaining it a bit more in detail, but for now I am just going to talk about using Commands.  Why, could you ask, well the main reason is that this is the biggest thing I was missing in Silverlight, a way to define ( in XAML ) how we want our UI to behave without having to attach unreadable event handlers like we would normally do.

For a detailed explanation on how commanding works you could visit the msdn website, but for a simple, back to basics solution, please read on.

MVVM

To illustrate our point we are going to create an MVVM application, what MVVM is and how we should work with it is something we will talk about in one of my next posts.  The think here is that we will not have any code behind in our View ( Page ) and we will databind our ViewModel to it to be able to do some commanding.

The XAML code :

This is the xaml code we will place in our view class, for example “MainPage.xaml”, the code behind will be empty, appart from the standard InitializeComponent() call.

<UserControl.DataContext>
<local:ViewModel/> 
</UserControl.DataContext>
<Grid x:Name="LayoutRoot"> 
<StackPanel Orientation="Vertical">
 
<TextBlock Text="Please enter the answer : "/>
 
<TextBox Text="{Binding TextValue}" x:Name="answer"/>
  <Button Content="Ok" composite:Click.Command="{Binding ConfirmCommand}" 
     composite:Click.CommandParameter="{Binding ElementName=answer,
   
Path=Text}"  /> 
<StackPanel>
</Grid>

The ViewModel

This is the ViewModel, this is a concept that I will explain in further detail in future posts, but the idea is that this ViewModel is databound to the View ( as we can see in the DataContext property in the View )

public class ViewModel : INotifyPropertyChanged

public ViewModel()

//Initialize the command, hooking up the execute method and the canexecute method 
ConfirmCommand = new DelegateCommand<string>(execute, canExecute);
}

 

/// <summary>
/// Execute the command when it was clicked
/// </summary>
/// <param name="parameter">The Command Parameter that was given</param> 
private void execute(string parameter) 

MessageBox.Show(string.Format("You have succesfully answered : {0}", parameter)); 

/// <summary> 
/// Can we execute the command, this will disable the related control if it cannot
/// </summary> 
/// <param name="parameter">The command parameter that was given</param>
/// <returns>Can the command execute</returns>
private bool canExecute(string parameter)
{
//Can we execute the command
return parameter == "42";
}

private string textValue;
/// <summary>
/// Definition of our bindeable TextValue, with a trigger to update the UI
/// </summary>

public string TextValue
{
get { return textValue; }
set
{
 
textValue = value;
  //Notifiy the property has changed
  InvokePropertyChanged("TextValue");
  //Notify the command that the conditions to execute have changed
  ConfirmCommand.RaiseCanExecuteChanged();
}
}

public DelegateCommand<string> ConfirmCommand { get; set; } 

/// <summary>
/// Track changes to the Properties, so the UI can know when to update the bindings.
/// </summary>

public event PropertyChangedEventHandler PropertyChanged;

private void InvokePropertyChanged(string property){
 
if (PropertyChanged != null)
   
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}

So what exactly does this application do ?  Well basically it check if your entered text in a textbox is equal to “42” and enables the Button if so.  Nothing to complicated, just the answer to life the universe and everything (link).

Conclusion

I hope it is clear by this example what power Commanding has in Silverlight ( just like in WPF ) and how we can benefit from using it more extensively. Mainly the CanExecute makes a huge difference in how you can easily allow an application to respond to your input and adapt.

2 comments:

  1. Since your example has an element-to-element binding i'll mention that it sucks ;)

    http://groups.google.com.au/group/wpf-disciples/browse_thread/thread/deec281c218ec647/cc4a66fc48ee4647?lnk=raot

    ReplyDelete
  2. I agree, I actually never use it myself. I basically used it here to illustrate the possiblity to add a parameter to the command.

    Thanks for the reply though :)

    ReplyDelete