WPF command parameter for button inside ItemsControl

I am developing a WPF application using the MVVM design pattern. In the application, I have an ItemsControl element that displays several buttons (the number of buttons is not constant, according to the logical flow of the application). The ItemsControl element is bound to a LinkedList in the ViewModel. I can define a command for the buttons, and I can get the command handler in the ViewModel only if the command has no parameters ... I need to know which button is pressed, and therefore I would like to have a command with a parameter.

How do I determine my appearance? What is the Syntax for CommandParameter and what parameter can I use to get Button content? What will be the signature of the command in ViewModel?

Please note that I am using RelayCommand from MVVM Light. The relvant view code is here. thanks in advance

<UserControl x:Class="Museum.Controls.CategoriesView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="130" d:DesignWidth="418"> <UserControl.Resources> <DataTemplate x:Key="CategoriesButtonsTemplate"> <Button Content="{Binding }" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}, Path=DataContext.CategorySelectedCommand}" /> </DataTemplate> </UserControl.Resources> <Grid ShowGridLines="True"> <Grid.RowDefinitions> <RowDefinition Height="50"></RowDefinition> <RowDefinition Height=" 40"></RowDefinition> <RowDefinition Height=" 40"></RowDefinition> </Grid.RowDefinitions> <Grid x:Name="SubSubjectGrid" Grid.Row="0"></Grid> <Grid x:Name="CategoriesGrid" Grid.Row="1"> <ItemsControl Grid.Row="1" ItemsSource="{Binding Path=CategoriesButtons}" ItemTemplate="{StaticResource CategoriesButtonsTemplate}" > <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </Grid> <Grid x:Name="SelectedCategoryGrid" Grid.Row="2"></Grid> </Grid> </UserControl> 
+6
source share
3 answers

You can simply use CommandParameter = "{Binding}", like this

  <DataTemplate x:Key="CategoriesButtonsTemplate"> <Button Content="{Binding }" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}, Path=DataContext.CategorySelectedCommand}" CommandParameter="{Binding }" /> </DataTemplate> 
+7
source

MVVM Light has a common RelayCommand class that can handle command parameters. The non-generic RelayCommand class ignores them. Here is an example:

Bind the CommandParameter property first, as Ahmed showed in his answer:

  <Button Content="{Binding}" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}, Path=DataContext.CategorySelectedCommand}" CommandParameter="{Binding}" /> 

Lets say the linked list for buttons in your viewmodel is a list of strings. The contents of your button and your CommandParameter are tied to one of your list items. Now create a generic RelayCommand repeater in your view model:

  private RelayCommand<String> mOnClickCommand; public RelayCommand<String> ClickCommand { get { return mOnClickCommand; } } 

Create it like this, for example, in your constructor:

  mOnClickCommand = new RelayCommand<string>(OnButtonClicked); 

And finally, in your method, you will get the CommandParameter property as an argument to the method:

  private void OnButtonClicked(String _category) { Console.WriteLine(_category); } 

Hope this will be helpful.

+1
source

You can use the interactivity and iteration libraries. In this case, you should add this to your button xaml code:

 <Button> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ei:CallMethodAction TargetObject="{Binding}" MethodName="OnClick"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> 

And to view the model:

 public void OnClick(object sender, MouseEventArgs args) {// your code } 
0
source

Source: https://habr.com/ru/post/955384/


All Articles