Click.Command Unknown Attribute (Silverlight)

Feb 24, 2009 at 12:02 PM
I am trying to implement something in Silverlight and WPF. The Click.Command exists for both. In WPF it is working fine.
But in Silverlight I get an error:
Unknown Attribute "Click.Command" for Element "Button".

Here is how I defined the Button:



<Button Content="Speichern" Margin="0,4,137,4" Width="60" Height="25" 
HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Row="1"
prism:Click.Command="{x:Static presenters:KontoCommands.SaveKontenCommand}"
Visibility="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.SaveVisibility}"/>


I am not sure what I am doing wrong. Any suggestions?

Feb 24, 2009 at 1:09 PM

x:Static is not supported by Silverlight you only can have StaticResource.

On the other hand RelativeSource is also not supported by Silverlight 2.

Check out the StockTrader RI for Silverlight to get a working sample for the Command. For the visibility you should try to use a Model variable binding with a ValueConverter which looks up the ItemsControl's DataContext for you. But since DataContext is assigned downwards the VisualTree afaik, your button should also has access to the same data within it's DataContext property, but I can't tell this from your snippet above.

Feb 24, 2009 at 2:02 PM
Edited Feb 24, 2009 at 2:19 PM
Oh. I did not know that..

Ok. The Command I can get to work with simple DataBinding, they are in the ViewModel. But only in the DataTemplate in which the Button is defined. But what do I have to do if I want to define a Button in the Shell and use my CommandProxy and the Commands? Couldn't find a sample in the StockTrader. Just samples where they use DataBinding...
And the enabling and disabling is not working like in WPF... Do I have to bind this too? And how?

Edit: My Error Sorry. It is not working with Databinding.. Same Problem as described below. Need to find the overlaying DataContext somehow...

The visibility is more complex. Thought it would work the same way. But as you say, there is no RelativeSource... The Problem is, that the Button is in a DataTemplate for a rowdetails of a Datagrid. The ViewModel is assigned to the whole Datagrid and there is the visibility and everything else set. But the Buttons are shown when one Row is selected and because of that for the button not the whole set (ViewModel) is the datacontext but only one Item in the set. I get BindingErrors saying that SaveVisibility is not defined on that item. I need a way to go up like in WPF....
Feb 24, 2009 at 2:16 PM
DataTemplate's should also get the DataContext property propagated. Add a Click handler within your DataTemplate to your button and check the DataContext property, what's it holding? where is it pointing to?

Can't you add a Parent property to your ViewModel's "per row" data type? that way you can walk up to the whole dataset.

If you'd like to have a per row visibility why can't you propagate that value to the per row datacontext items? What is the base of the determination of the button's visibility why you need the whole data set?
Feb 24, 2009 at 2:36 PM
I have to use a bunch of autogenerated Classes and some Interfaces I can not change. Because of that I only have a ViewModel for the Set and not for single Items.
The single Items are only displayed by DataTemplates and with DataBinding. They have no real funtionality. Things like saving are done with the set.

To make the situation a bit clearer:

We have a View which gets the ViewModel as DataContext. In the View there is a DataGrid which ItemsSource ist set to Binding. Now we have rows and for this rows a DetailsTemplate. This Template only gets the single Items as DataContext. I know this because I used the DataContext in a Converter. And now the Button. The Button is in the Template too. But all the visibility and command stuff is in the ViewModel. Out of reach for the button. How to get there?
Are Commands comming in Silverlight 3? Does anybody know? Would fix the whole problem I think...
Feb 24, 2009 at 7:45 PM

This is a limitation in Silverlight. It would be much easier if we had RelativeSource or ElementName in Binding. Let’s hope for it in SL3 :)

In order to workaround it, you have some options.
If the command you are trying to bind to is a global command (and not an instance command hanging from your ViewModel), and I guess it is your case because you were first using the x:Static markup, then the solution is pretty easy.
You need to create a command proxy class that expose the commands.
Then add this class to the Resources (either in App.xaml or in your UserControl for the view)
Bind to the command using StaticResource in the Source property

public class KontoCommandsProxy
  public ICommand SaveKontenCommand { get { ... } }

<UserControl ... >
  <presenters:KontoCommandsProxy x:Key="KontoCommandsProxy" />
    <Button Click.Command="{Binding SaveKontenCommand, Source={StaticResource KontoCommandsProxy}}" ... />

In case this is an instance command and not a global one, you can check out the PositionSummaryView in the StockTrader RI, which handles this scenario, although the workaround is a little more complex than this one, due to the lack of DynamicResource in SL again.

I hope this helps,
Julian Dominguez

Feb 25, 2009 at 7:16 AM
Edited Feb 25, 2009 at 8:24 AM
Thank you so much! That is exactly what I am looking for. Again such a simple sulotion. There are times when I notice that I just started one month ago with WPF and Silverlight...

But the Visibility thing is not solved. Perhaps I just have to wait until SL3...

Edit: I got it working, in fact it is working nearly perfect.. But the enabled Status is not updated correctly... When I edit something in a details template nothing happens to my Buttons. When I select another Row there the Buttons are enabled and dsabled as they should. Do I have to Refresh the pasge after each edit?? In the WPF implementation this works fine and the debugging shows that everything is the right way.
Feb 27, 2009 at 8:14 AM
I still need you help.
I don't get the Buttons enabled and disabled correctly. I don't know why. As I said before The ViewModel returns the right values for the enabledstate but the buttons do not do what they should do. Only when I click into another row the buttons in the new row get enabled. But when I click an Button I am getting errors because the state does not fit the changes made. Even if I change back into the row where I made the changes the buttons are still disabled.
Is this a bug or something else?