I have run into an issue with WPF and Commands that are bound to a Button inside the DataTemplate of an ItemsControl. The scenario is quite straight forward. The ItemsControl is bound to a list of objects, and I want to be able to remove each object in the list by clicking a Button. The Button executes a Command, and the Command takes care of the deletion. The CommandParameter is bound to the Object I want to delete. That way I know what the user clicked. A user should only be able to delete their "own" objects - so I need to do some checks in the "CanExecute" call of the Command to verify that the user has the right permissions.
The problem is that the parameter passed to CanExecute is NULL the first time it's called - so I can't run the logic to enable/disable the command. However, if I make it allways enabled, and then click the button to execute the command, the CommandParameter is passed in correctly. So that means that the binding against the CommandParameter is working.
The XAML for the ItemsControl and the DataTemplate looks like this:
<ItemsControl
x:Name="commentsList"
ItemsSource="{Binding Path=SharedDataItemPM.Comments}"
Width="Auto" Height="Auto">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button
Content="Delete"
FontSize="10"
Command="{Binding Path=DataContext.DeleteCommentCommand, ElementName=commentsList}"
CommandParameter="{Binding}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
So as you can see I have a list of Comments objects. I want the CommandParameter of the DeleteCommentCommand to be bound to the Command object.
So I guess my question is: have anyone experienced this problem before? CanExecute gets called on my Command, but the parameter is always NULL the first time - why is that?
Update: I was able to narrow the problem down a little. I added an empty Debug ValueConverter so that I could output a message when the CommandParameter is data bound. Turns out the problem is that the CanExecute method is executed before the CommandParameter is bound to the button. I have tried to set the CommandParameter before the Command (like suggested) - but it still doesn't work. Any tips on how to control it.
Update2: Is there any way to detect when the binding is "done", so that I can force re-evaluation of the command? Also - is it a problem that I have multiple Buttons (one for each item in the ItemsControl) that bind to the same instance of a Command-object?
Update3: I have uploaded a reproduction of the bug to my SkyDrive: http://cid-1a08c11c407c0d8e.skydrive.live.com/self.aspx/Code%20samples/CommandParameterBinding.zip
This is an old thread, but since Google brought me here when I had this issue, I'll add what worked for me for a DataGridTemplateColumn with a button.
Change the binding from:
to
Not sure why it works, but it did for me.
I stumbled upon a similar problem and solved it using my trusty TriggerConverter.
This value converter takes any number of parameters and passes the first of them back as the converted value. When used in a MultiBinding in your case it looks like the following.
You will have to add TriggerConverter as a resource somewhere for this to work. Now the Command property is set not before the value for the CommandParameter has become available. You could even bind to RelativeSource.Self and CommandParameter instead of . to achieve the same effect.
There's a relatively simple way to "fix" this problem with DelegateCommand, though it requires updating the DelegateCommand source and re-compiling the Microsoft.Practices.Composite.Presentation.dll.
1) Download the Prism 1.2 source code and open the CompositeApplicationLibrary_Desktop.sln. In here is a Composite.Presentation.Desktop project that contains the DelegateCommand source.
2) Under the public event EventHandler CanExecuteChanged, modify to read as follows:
3) Under protected virtual void OnCanExecuteChanged(), modify it as follows:
4) Recompile the solution, then navigate to either the Debug or Release folder where the compiled DLLs live. Copy the Microsoft.Practices.Composite.Presentation.dll and .pdb (if you wish) to where you references your external assemblies, and then recompile your application to pull the new versions.
After this, CanExecute should be fired every time the UI renders elements bound to the DelegateCommand in question.
Take care, Joe
refereejoe at gmail
Beside Ed Ball's suggestion on setting CommandParameter prior to Command, make sure your CanExecute method has a parameter of object type.
Hope it prevents someone spending the huge amount of time I did to figure out how to receive SelectedItems as CanExecute parameter
I know this thread is kind of old, but I've come up with another option to work around this issue that I wanted to share. Because the CanExecute method of the command gets executed before the CommandParameter property is set, I created a helper class with an attached property that forces the CanExecute method to be called again when the binding changes.
And then on the button you want to bind a command parameter to...
I hope this perhaps helps someone else with the issue.
Some of these answers are about binding to the DataContext to get the Command itself, but the question was about the CommandParameter being null when it shouldn't be. We also experienced this. On on a hunch, we found a very simple way to get this to work in our ViewModel. This is specifically for the CommandParameter null problem reported by the customer, with one line of code. Note the Dispatcher.BeginInvoke().