WPF CommandParameter is NULL first time CanExecute is called
I was having this same issue while trying to bind to a command on my view model.
I changed it to use a relative source binding rather than referring to the element by name and that did the trick. Parameter binding didn't change.
Old Code:
Command="{Binding DataContext.MyCommand, ElementName=myWindow}"
New Code:
Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource AncestorType=Views:MyView}}"
Update: I just came across this issue without using ElementName, I'm binding to a command on my view model and my data context of the button is my view model. In this case I had to simply move the CommandParameter attribute before the Command attribute in the Button declaration (in XAML).
CommandParameter="{Binding Groups}"
Command="{Binding StartCommand}"
I have found that the order in which I set Command and CommandParameter makes a difference. Setting the Command property causes CanExecute to be called immediately, so you want CommandParameter to already be set at that point.
I have found that switching the order of the properties in the XAML can actually have an effect, though I'm not confident that it will solve your problem. It's worth a try, though.
You seem to be suggesting that the button never becomes enabled, which is surprising, since I would expect the CommandParameter to be set shortly after the Command property in your example. Does calling CommandManager.InvalidateRequerySuggested() cause the button to become enabled?
I stumbled upon a similar problem and solved it using my trusty TriggerConverter.
public class TriggerConverter : IMultiValueConverter
{
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// First value is target value.
// All others are update triggers only.
if (values.Length < 1) return Binding.DoNothing;
return values[0];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
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.
<ItemsControl
x:Name="commentsList"
ItemsSource="{Binding Path=SharedDataItemPM.Comments}"
Width="Auto" Height="Auto">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button
Content="Delete"
FontSize="10"
CommandParameter="{Binding}">
<Button.Command>
<MultiBinding Converter="{StaticResource TriggerConverter}">
<Binding Path="DataContext.DeleteCommentCommand"
ElementName="commentsList" />
<Binding />
</MultiBinding>
</Button.Command>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
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.