Using RelayCommands in Silverlight 3 and WPF

Like most of us have found out the hard way, Silverlight 3 and Windows Presentation Foundation 3.5 are two quite similar beasts, but not totally the same. Silverlight is often presented as a subset of WPF (in fact, some features are available in Silverlight but not yet in WPF; generally speaking, though, it is true that Silverlight has less features than its big sister WPF) (yeah WPF is a girl, don’t tell me you didn’t know ;))

Read the rest of this entry »

Print | posted on Saturday, September 26, 2009 7:15 AM

Feedback

# re: Using RelayCommands in Silverlight and WPF

left by Josh at 9/26/2009 8:33 PM Gravatar
This feature is already implemented in Prism/CAG almost identically:

http://prism.codeplex.com/

In V2 which released in February. It also contains a DelegateCommand which is similar to RelayCommand but based on John Gossman's original from Blend.

# re: Using RelayCommands in Silverlight and WPF

left by Laurent Bugnion at 9/26/2009 10:00 PM Gravatar
Hi Josh,

You are right, and this is not the only thing that is similar to what Prism is offering. As I mentioned on your own blog, I also have a Messenger which is an implementation of the Event Aggregator.

The goal of the toolkit is to offer an alternative, directly targeted at MVVM (while Prism is targeted at composite applications, with some of the elements that can be used for MVVM), and in a form that works best with Expression Blend. This is a lighter framework than Prism, which should be easier to start with, and which integrates better in Blend for the design time experience.

Glenn Block and I argued a LOT about reusing pieces of Prism, packaging them differently, or implementing something slightly different. I chose the second approach mostly because this gives me more flexibility in pushing changes that the community requests. This is already what happened with the Messenger V2 (I will post the beta later today), and I expect the same to happen to other pieces too). I think that Glenn (who was an alpha tester) agrees with me that the toolkit is a very light and flexible approach to MVVM, and easy to integrate in existing applications (including those built with IoC etc...).

Thanks for your feedback, and don't hesitate to give more if you have suggestions.

Cheers,
Laurent

# re: Using RelayCommands in Silverlight and WPF

left by Raghuraman at 10/4/2009 11:02 AM Gravatar
Great Work Guys !!!

This will pull down the learning curve for wannabe MVVM implementations in SL.

Keep it up.

# re: Using RelayCommands in Silverlight and WPF

left by ETFairfax at 10/19/2009 8:20 PM Gravatar
Hi,

I'm brand new to all of this Silverlight/MVVM stuff, so please be gentle!!

If I have a user control which hass two buttons and include that on my page. Is it possible to add a command to the Click event of each of the two buttons? Something like....

<uc:MyUserControl SaveEvent="{Binding Path=SaveCommand}" CancelEvent="{Binding Path=CancelCommand}" />

I've got commands working with single buttons i.e...

<Button Content="Delete" cmd:ButtonBaseExtensions.Command="{Binding Path=DeleteCommand}" />

But can't work out what i need to do to make this work on a user control.

Does that make sense??

Cheers,

ETFairfax.

# re: Using RelayCommands in Silverlight and WPF

left by Laurent at 10/19/2009 9:50 PM Gravatar
Hi,

It does make a lot of sense. Historically, this restriction comes from WPF, where only some controls (all ButtonBase, MenuItems...) implement ICommandSource, which specify the Command property. Only these controls can have a Command, and the command is only activated on Click event.

Thankfully, there are ways around that, and I am working on a new version of the MVVM Light toolkit that will include a "Event to Command" binder. It will be strongly inspired from works by the Expression Blend team as well as Orktane's nRoute toolkit, so in the mean time I encourage you to check these.

If you prefer to stick with the MVVM Light toolkit, one transient measure you can take is to handle the event in the code behind, and execute the command from there. This way, when the EventToCommand binder is available, you can just remove the code behind and do that in the XAML instead.

http://expressionblend.codeplex.com/

http://www.orktane.com/Blog/post/2009/10/10/Introducing-nRouteToolkit-for-Silverlight-(Part-II).aspx

Cheers,
Laurent

# re: Using RelayCommands in Silverlight and WPF

left by ETFairfax at 10/20/2009 9:15 PM Gravatar
Nice one Laurent. I'll have a look at those resources.

I look forward to the next release of the toolkit.

Thanks,
ETFairfax

# re: Using RelayCommands in Silverlight 3 and WPF

left by Werner at 1/19/2010 11:12 PM Gravatar
Hi!

Any news on that EventToCommand binder?

Really really would like that. PRISM's way of getting custom events to work is way way way to involved for my taste.

;)

# re: Using RelayCommands in Silverlight 3 and WPF

left by Laurent at 1/19/2010 11:40 PM Gravatar
Hey Werner,

Yes, EventToCommand is available in the latest release of the toolkit. See
http://blog.galasoft.ch/archive/2009/11/13/bug-correction-in-messenger-and-new-feature-in-eventtocommand-mvvm.aspx

and also

http://blog.galasoft.ch/archive/2009/12/17/silverlight-4-dragampdrop-with-eventtocommand.aspx

Hope this helps!
Laurent

# re: Using RelayCommands in Silverlight 3 and WPF

left by Werner at 1/20/2010 12:22 AM Gravatar
That is excellent news. I have found those extentions hiding in "extras".

I have another question. For some bizarre reason I cannot find the ButtonBaseExtensions part of the Commanding inside your MVVM.Lite library.

What am I misssing? If I do a keyword search throughout MVVM.Lite I find now references to that name. I am under the understanding that it must come from MVVM.Lite?

What am I not getting here?

# re: Using RelayCommands in Silverlight 3 and WPF

left by Laurent at 1/20/2010 12:40 AM Gravatar
Hi,

ButtonBaseExtension is only needed (and available) in the Silverlight 3 version of the toolkit. In the WPF 3.5, WPF 4 and Silverligh 4 versions, you should use the built-in property Command which is available on all ButtonBase instances.

In the Silverlight 3 version, this class is available in the GalaSoft.Mvvm.Command namespace.

Make sure that you have the correct version of the DLLs if you need this class!

Cheers,
Laurent

# re: Using RelayCommands in Silverlight 3 and WPF

left by Werner at 1/20/2010 12:46 AM Gravatar
Aah!

I did not know this.

I am indeed working with SL4. I was aware that SL4 has some commanding support, but also just on buttons. It's your EventToCommand binder I was aftet so I did not check was already available in SL4

The commanding is working now.

Thanks allot!

Werner

PS - Awesome toolkit I like it

# re: Using RelayCommands in Silverlight 3 and WPF

left by Dave at 2/25/2010 4:55 AM Gravatar
Great article! I am planning on using your toolkit, but am currently looking into problems where my GUI doesn't actually update as expected; when properties that govern whether my command CanExecute or not change, the GUI doesn't update unless I actually click. Just moving the mouse isn't enough. I am thinking about calling InvalidateRequerySuggested in a Timer for now, until I can implement your toolkit. What are your thoughts on that? Oh, and I'm using WPF with .NET 3.5 SP1

# re: Using RelayCommands in Silverlight 3 and WPF

left by Arun at 8/27/2010 7:59 PM Gravatar
Hi,
I want to add Controls dynamically from ViewModel. I have to add Button and Textbox dynamically to the Grid. In the ViewModel constructor call I need to add the controls. I am not getting how to get the Grid control reference in my ViewModel. Can anybody help me on this?
Thanks in advance

# re: Using RelayCommands in Silverlight 3 and WPF

left by Andy at 8/30/2010 8:52 AM Gravatar
Hey Laurent,
I'm working on a MVVM Application using your toolkit. I am building a Silverlight and WPF version, and would like to reuse part as much as possible. I have everything working except the Views.

Say I have a MainView in my Silverlight application, which my WPF application has added as a link. I run into a problem trying to build because of the EventToCommand behavior namespace which uses the MvvmLight.Extras.SL4, where as the WPF uses the Extras.WPF equivalent. So, my WPF version throws an error on the MainView.

What is the best way to link XAML views between Silverlight & WPF using your toolkit (which is AWESOME by the way... MVVM rocks)?
Thanks

# re: Using RelayCommands in Silverlight 3 and WPF

left by Rick Ratayczak at 8/30/2010 10:56 AM Gravatar
Andy, it is better if you make the WPF app first, using Visual State Manager and not triggers, than it is easier to port to silverlight, versus the other way around.

# re: Using RelayCommands in Silverlight 3 and WPF

left by Andy at 8/31/2010 4:32 AM Gravatar
Rick,
Thanks for the reply. Won't I run into the same problems (with the Extras.WPF vs SL)?

Currently, I fixed the issue by just using built in button commands for silverlight, and modifying the application so my EventToCommand controls could be cut out. I was then running into toolkit issues (DatePicker and Wrap Panel, in particular) where they are built into WPF, but in the Silverlight toolkit. Thus, the toolkit namespace did not apply to WPF version.

Does it really make it that much easier to share views, as I am trying to do, when you do WPF first? I just thought doing SL first would be easier because "everything" in SL you can do in WPF, but not the other way around.

# re: Using RelayCommands in Silverlight 3 and WPF

left by Sung Kim at 9/5/2010 3:41 PM Gravatar
> “Add as a link”
What is the advantage of using “Add as a link” instead of creating a common library?
Saving lines?

# re: Using RelayCommands in Silverlight 3 and WPF

left by Laurent at 9/6/2010 12:18 AM Gravatar
There is an issue of binary compatibilty that adding as Link solves. Silverlight 3 is not binary compatible (well, almost not) with WPF. Silverlight 4 is better, but not quite there yet. As for WP7, it's even worse. By using Add as link, you don't have this issue at all.

Makes sense?
Laurent

# re: Using RelayCommands in Silverlight 3 and WPF

left by roberto at 9/14/2010 1:08 AM Gravatar
Hello Laurent, i'm using your toolkit to build my first application in sl4, i'have a problem when i navigate from a view to another:
I call base.CleanUp, but (and i see this with winDBG) the view and the viewmodel still stay in memory.

Could be a related problem to some link beetween viewmodel and view caused by relayCommand?

# re: Using RelayCommands in Silverlight 3 and WPF

left by Brijen at 9/15/2010 5:04 AM Gravatar
I am using your toolkit for WP7. What's the guideline to move from Page 1 to Page 2. I have button on page 1 and on click event want to move to page 2.

Could you please share the sample code or app...

# re: Using RelayCommands in Silverlight 3 and WPF

left by dan at 9/17/2010 1:12 AM Gravatar
I'm falling in love with this framework, but you really REALLY need to have more samples or documentation. As it is, it's mostly "just figure it out".

Specifically regarding this example, for it to be complete you should really show how you would impose a Counter limit and actually use CanIncrement.

Looking forward to figuring out more of this!

# re: Using RelayCommands in Silverlight 3 and WPF

left by dan at 9/17/2010 1:14 AM Gravatar
Also, I understand the interest in proving it possible, but what is the value of sharing 100% code between WPF and SL. You'd obviously have to program to the lowest common denominator (SL), so at that point why even bother with WPF? Or is it just an exercise to prove it's possible?

Does WPF not require an additional installation beyond the .Net framework? Is that the advantage of WPF over SL in this scenario (developing both)?

# re: Using RelayCommands in Silverlight 3 and WPF

left by andrew lindzon at 10/3/2010 4:40 AM Gravatar
I am just getting started with MVVM Light, and I am trying to figure out how to communicate a close request to the MainPage so it can close the current tab. The user will click on a button which will trigger a command in the CustomerView which will first deal with any data issues using the customerviewmodel, then it needs to tell the MainPage to terminate the view and close the current tab.

How would you do that?

# re: Using RelayCommands in Silverlight 3 and WPF

left by ursri at 10/27/2010 9:43 PM Gravatar
Hi,
Can dynamic method parameters set to relaycommand using method name and reflection techniques?

Thanks
ursri

# re: Using RelayCommands in Silverlight 3 and WPF

left by Michael Stone at 11/15/2010 11:37 PM Gravatar
I'm using the latest version of the toolkit and RelayCommand does not seem to have the RaiseCanExecuteChanged method. Has that been removed in the latest release? If so, what should I use instead?

Thanks

# re: Using RelayCommands in Silverlight 3 and WPF

left by Shawn Featherly at 3/4/2011 2:00 AM Gravatar
@dan, CanIncrement is used by the dis/enable button. Add a counter limit by adding a condition to the Counter property's set: block
else if (value == 10) CanIncrement = false;

After trying to make it decrement after hitting 10, I found changing the RelayCommand's Action execute after it was set didn't work as I wanted, neither by setting IncreaseCounterCommand to a new RelayCommand or by using IncreaseCounterCommand.Execute(new Action(() => Counter--)).

The working method I found was making the execute action not need to be changed, to more flexible. I used "Counter += step" instead of "Counter++". "step" being a private integer that was changed in the "else if (value == 10)".

# re: Using RelayCommands in Silverlight 3 and WPF

left by Vijay at 3/15/2011 6:05 AM Gravatar
I do not see reply to Andy's problem. Was just thinking if Attached Command Behavior would solve the problem. I am not sure if ACB is supported by SL or not, but works well with WPF.

# re: Using RelayCommands in Silverlight 3 and WPF

left by Allen Marshall at 3/21/2011 12:56 PM Gravatar

I do not seem to be able to use the version of RelayCommand<T> as shown below. I get the message "Cannot implicitly convert type ....RelayCommand<Theme> to ...RelayCommand
Is there some magic to passing an argument to a relay command or am I just clueless? Or worse, is the argument mandated to be a simple type?

/// <summary>
/// Switch the theme application wide
/// </summary>
public bool CanSwitchTheme
{
get
{ return true; }
}
private RelayCommand _switchThemeCommand;

public RelayCommand SwitchThemeCommand
{
get
{
if (_switchThemeCommand == null)
{
_switchThemeCommand = new RelayCommand<Theme>(( Theme param ) => LookAndFeelHelper.SwitchTheme(param),
(Theme param) => this.CanSwitchTheme);
}
return _switchThemeCommand;
}

}

# re: Using RelayCommands in Silverlight 3 and WPF

left by Allen Marshall at 4/12/2011 12:47 AM Gravatar
This question still remains.... any ideas?

# re: Using RelayCommands in Silverlight 3 and WPF

left by Laurent Bugnion at 4/18/2011 3:05 PM Gravatar
Hi,

Well RelayCommand<T> is not the same type than RelayCommand. If you want to use the code, you need to do

private RelayCommand<Theme> _switchThemeCommand;

Alternatively, this is also possible:

private ICommand _switchThemeCommand;

Cheers,
Laurent

# re: Using RelayCommands in Silverlight 3 and WPF

left by Allen Marshall at 4/19/2011 1:55 PM Gravatar
Yes, thank you. I must have mistyped, because the <T> approach was the desired one. I solved this by the following, and it works nicely, but is this ridiculous? Should I have been able to pass the Theme object as originally intended?

...
// SwitchThemeCommand - switch theme on theme selection
// takes a string argument containing an internal theme name from the Telerik Themes collection
SwitchThemeCommand = new RelayCommand<string>((t) => LookAndFeelHelper.SwitchTheme(t),
(t) => CanSwitchTheme);
...

# re: Using RelayCommands in Silverlight 3 and WPF

left by KennyWoo at 4/24/2011 11:05 AM Gravatar
I have just started to learn about MVVM Light .
It's strong and MVVM - oriented but i got a problem with it.
When i create a command CheckUser via RelayCommand on my ViewModel,i just found the RelayCommand<T> with only one parameter
I want something like CheckUser=new RelayCommand<string,string>((user,pass)=>....)
How can i do this with RelayCommand multi param or some method to resolve my problem.

# re: Using RelayCommands in Silverlight 3 and WPF

left by Laurent Bugnion at 4/25/2011 11:38 AM Gravatar
Hi,

The fact that there is only one parameter in commands is not due to MVVM Light, but to the ICommand interface, which is defined by Microsoft. The Execute method defined by this interface has only one parameter (which may be null).

Typically when you need more than one parameter, there are other ways to go around this limitation. For instance, data bind some properties of your ViewModel to some elements of your view. Then, when the command is executed, you can read the value of these properties to configure your method call.

HTH,
Laurent

# re: Using RelayCommands in Silverlight 3 and WPF

left by KennyWoo at 4/25/2011 1:43 PM Gravatar
Dear Laurent,

I still confuse about how do i resolve some method like as CheckLogin(string username,string pass) or InsertNewUser(string username,.....with multi param) from original WPF/Silverlight Project to MVVM pattern.
Can you give me some solution or sample to resolve my problem .
I developed WPF/Silverlight with no pattern before and now i've just moved to MVVM in few days.
I choose MVVM Light among so may MVVM framework like as Prism,Catel,Cinch,...
So you can give me some document about MVVM Light ?
Thanks & regard.

# re: Using RelayCommands in Silverlight 3 and WPF

left by Milind Chavan at 5/26/2011 10:45 AM Gravatar
Hi Laurent,
I am using MVVM light for the WPF application. The application uses the EventToCommand to bind the Icommand to Realycommand.

public ICommand Image_MouseLeftButtonUp
{
get { return _Image_MouseLeftButtonUp ?? (_Image_MouseLeftButtonUp = new RelayCommand((param) => this.Image_OnMouseLeftButtonUp())); }
private set { _Image_MouseLeftButtonUp = null; }
}

But I would like to know, how to deregister/unhook the binding with RelayCommand ?

Regards,
Milind.

# re: Using RelayCommands in Silverlight 3 and WPF

left by kamlendra at 6/24/2011 11:00 AM Gravatar
i am able to bind event to Icommand directly in XAML just one doubt.
how can i pass the argument like (object sender,EventArgs args)
w'll it be using commandparameter if yes please tell me the way.

# re: Using RelayCommands in Silverlight 3 and WPF

left by Laurent Bugnion at 6/28/2011 11:15 AM Gravatar
Hi,

You can pass only one parameter to an ICommand implementation. Use the CommandParameter property for this.

Cheers,
Laurent

# re: Using RelayCommands in Silverlight 3 and WPF

left by Andrew Strickland at 7/29/2011 8:28 PM Gravatar
Hi Laurent, I'm new to MVVM but I love it. Your toolkit has been a huge help, and your code and videos is quite clear.

I have a ComboBox in my XAML that is using the RelayCommand with EventToCommand that is fired when the ComboBox's SelectionChanged event is triggered.

My ViewModel has this handler:

HandleSuffixChangedComamnd = new RelayCommand<SelectionChangedEventArgs>(e =>
{
if(IsOtherSuffixSelected(e.AddedItems[0].ToString()))
{

}
});

The IsOtherSuffixSelected method checks the value of the selected item so see it it matches a value of "__Other__". What I want to do now is make a TextBox in the XAML display conditionally dependant on whether that returns true. What is the best way to do this while following the MVVM pattern? After all, the ViewModel shouldn't know anything about the View.

I assume I'm supposed to fire a manual property changed of some kind, and the TextBox would bind to that property somehow in it's "Visibility" property?

# re: Using RelayCommands in Silverlight 3 and WPF

left by Laurent at 7/29/2011 9:07 PM Gravatar
Hi,

When we say that the VM should not know the view, we mean that it shouldn't have a dependency on the view, because this complicates testing and maintainability (amongst other things). However, I see the VM as a kind of musical conductor for the orchestra that is the view. If you want to show/hide elements based on things happening in the VM, it is OK to have a corresponding property in the VM. For instance, imagine that you want to hide the login panel when the user is logged in. You can have two properties IsLoggedIn and LoginPanelVisibility. When IsLoggedIn changes (in the setter), you can RaisePropertyChanged for LoginPanelVisibilityPropertyName. The LoginPanelVisibility property only has a getter and returns Visible when IsLoggedIn is false, and vice versa.

This way you can easily add dependent properties in your VM. Having a property of type "Visibility" is OK, because you can easily unit test that this property changes depending on the status of IsLoggedIn..

Does it make sense?

Cheers,
Laurent

# re: Using RelayCommands in Silverlight 3 and WPF

left by Andrew Strickland at 7/29/2011 10:18 PM Gravatar
It does. I added the property:

/// <summary>
/// Gets the DisplayOtherSuffixText property.
/// </summary>
public bool DisplayOtherSuffixText
{
get
{
return _blnDisplayOtherSuffix;
}

set
{
if (_blnDisplayOtherSuffix == value)
{
return;
}

_blnDisplayOtherSuffix = value;

// Update bindings, no broadcast
RaisePropertyChanged(DisplayOtherSuffixTextPropertyName);
}
}

And set the value of that property in the RelayCommand Handler:

HandleSuffixChangedComamnd = new RelayCommand<SelectionChangedEventArgs>(e =>
{
if(IsOtherSuffixSelected(e.AddedItems[0].ToString()))
{
DisplayOtherSuffixText = true;
}
});

Then bound to that property in the XAML:

<TextBox x:Name="SuffixOtherText" Text="{Binding IdentifyingInformation.FullName.LegalName.Suffix_Other, Mode=TwoWay}" Grid.Column="2" Grid.Row="3" Visibility="{Binding DisplayOtherSuffixText, Converter={StaticResource BoolToVisibilityConverter}}" />

Oh, and created a simple converter that converts the bool from the property into a Visibility enum value. I guess I could have built that into the property itself but, this way I can re-use the converter elsewhere. Everything works now and it's all MVVM, no dependencies!

Thanks!

# Propertychange event and RelayCommand

left by EmanueleC70 at 10/25/2011 6:13 PM Gravatar
Hi, I have an issue i don't understand and resolve.
I have a datagrid and a button not directly linked to submitchange logic. I change a value in datagrid and without exit focus from that field i click the button.
I see the propery change event of my viewmodel called for the field change and HasChanges event of model, but it forget that i have clicked, so relaycommand does'nt fire. Thanks!

# re: Using RelayCommands in Silverlight 3 and WPF

left by Guido Smeets at 11/2/2011 2:27 PM Gravatar
I've noticed in WPF that at times the value of CanExecute and the enabledness of the button are out of sync. Whenever I interface with any UI element, it updates properly. This problem seems to mainly occur just after the user control has been loaded. I've fixed it with a manual call to InvalidateRequerySuggested for now, but this seems like an issue. Reading the other comments this seems to be the same problem that Dave brought up, any insights as to why this problem occurs?

# Mvvm Light Toolkit tutorial

left by Mojammel at 1/15/2013 12:16 PM Gravatar
Can anybody provide synchronized step by step tutorial for learning mvvm light toolkit?

I am very new in mvvm and want to learn about mvvm light but don't find any useful and synchronized tutorial for learning the toolkit.

Although some articles are available in net but what I saw that they aren't synchronized.

If anybody refer me any link for learning mvvm light a-z by an organized way please refer me or send me the documentation via mail. My mail address is mojampcds007@hotmail.com
Comments have been closed on this topic.