Execute command with parameter using xaml binding and viewmodel

Theun Arbeider picture Theun Arbeider · May 3, 2011 · Viewed 10.8k times · Source

Currently I have in xaml:

<ItemsControl ItemsSource="{Binding Facilities, Mode=OneWay}">
 <ItemsControl.ItemTemplate>
  <DataTemplate>
   <Border Style="{StaticResource BorderStyleHeader}">
    <Grid>
     <Grid.RowDefinitions>
      <RowDefinition Height="33" />
      <RowDefinition Height="33" />
     </Grid.RowDefinitions>
     <Grid.ColumnDefinitions>
      <ColumnDefinition Width="150" />
      <ColumnDefinition Width="*" />
     </Grid.ColumnDefinitions>
     <TextBlock Text="{Binding Name}" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="1" FontWeight="Bold" />
     <TextBlock Text="{Binding Description}" Grid.Row="1" Grid.Column="1" />
     <Button Content="Reserveer Nu" Style="{StaticResource ButtonStyle}" 
             Margin="5" Grid.Row="1" Grid.Column="0" 
             Command="{Binding Reservation.ItemClicked}" 
             CommandParameter="{Binding FacilityId}"/>
    </Grid>
   </Border>
  </DataTemplate>
 </ItemsControl.ItemTemplate>
</ItemsControl>

Now the first thing is that I wish for the button to raise the event in my viewmodel

public RelayCommand ItemClicked
{
    get
    {
        return new RelayCommand(() =>
        {
            MessageBox.Show("Something is clicked");
        });
    }
}

but it refuses...
secondly I want to be able to raise the event with a parameter (notice the commandparameter) but I have never used it and thus I dont understand how to use it.

So my questions:

  1. Why isn't my relaycommand being executed?

  2. How do I make use of the command parameter?

Answer

Thomas Levesque picture Thomas Levesque · May 3, 2011

Why isn't my relaycommand being executed?
How do I make use of the command parameter?

If you're using the RelayCommand class from Josh Smith's article, both questions have the same answer... The constructor takes an Action<object>, not an Action. So your code should be:

    return new RelayCommand((param) =>
    {
        MessageBox.Show("Something is clicked - Parameter value = " + param);
    });

EDIT: OK, so you're using the RelayCommand from MVVM Light... There are two versions of this class, one is generic and one is not. The non-generic version doesn't accept a parameter, so you need the generic version. Your command should look like this:

public RelayCommand<int> ItemClicked
{
    get
    {
        return new RelayCommand<int>((i) =>
        {
            MessageBox.Show("Something is clicked - Parameter value is " + i);
        });
    }
}

(assuming the parameter is of type int)

As for why your current code doesn't work, I can't answer without additional information...