user6183057
user6183057

Reputation: 25

Mvvm - How to capture in the ViewModel, which Button was pressed, using dataBinding command and Parameter Command? What am I not getting?

To simplify, Criticized for writing a novel w/no code a month ago, I made a quick wpf project (uses MVVM) with 2 buttons on the UI. When a button is clicked, I need my ViewModel to know which one, to route the Speech Synthesizer to the correct Text to Speak. Thanks 4 any help!!

Simple UI Image

<Window x:Class="Wpf_School_Announce.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Wpf_School_Announce"
        xmlns:vm="clr-namespace:Wpf_School_Announce.ViewModels"
        mc:Ignorable="d"
        Title="Announcements" Height="236.436" Width="293.218">
    <Window.Resources>
        <vm:ViewModelBase x:Key="viewModel"/>
    </Window.Resources>
    <Grid DataContext="{Binding Source=viewModel}">
        <StackPanel Margin="0,10">
            <Button x:Name="btn1stBell" Content="1st Bell" HorizontalAlignment="Center" VerticalAlignment="Top" Width="75" Margin="0,10" 
                     Command="{Binding ParameterCommand, Source={StaticResource viewModel}}" 
                    CommandParameter="{Binding Command, ElementName=btn1stBell}"/>
            <Button x:Name="btnLunchMenu" Content="Lunch Menu" HorizontalAlignment="Center" VerticalAlignment="Top" Width="75" Margin="0,10"
                     Command="{Binding ParameterCommand, Source={StaticResource viewModel}}" 
                    CommandParameter="{Binding Command, ElementName=LunchMenu}"/>
        </StackPanel>
    </Grid>
</Window>


namespace Wpf_School_Announce.ViewModels
{
    public class ViewModelBase
    {
        public ParameterCommand ParameterCommand { get; set; }

        public ViewModelBase()
        {
            ParameterCommand = new ParameterCommand(this);
        }

        public void ParameterMethod(string <Not sure what needs to go here>)
        {
           Debug.WriteLine("Parameter Comand:{0}", AnnoucementModel);
            //Todo: Need to find out which UI button was clicked to direct The Speech Synthesozer to the correct Speech Text.
        }
    }
}

namespace Wpf_School_Announce.ViewModels.Commands
{
    public class ParameterCommand : ICommand
    {
        public ViewModelBase ViewModel { get; set; }

        public ParameterCommand(ViewModelBase viewModel)
        {
            ViewModel = viewModel;
        }

        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            ViewModel.ParameterMethod(parameter as String);
        }
    }
}

Upvotes: 0

Views: 873

Answers (2)

J&#252;rgen R&#246;hr
J&#252;rgen R&#246;hr

Reputation: 941

It is a bad solution to just have one command on your viewmodel and to bind every button to it. If you have different things to be executed, define different commands. For that you either have to define a separate class with a dedicated Execute metod for each command or you can use something like RelayCommand of MvvmLight, where you can pass delegates upon creation of each command like this

public class ViewModelBase 
{
   public RelayCommand BellCommand...
   public RelayCommand LunchCommand...

   public ViewModelBase()
   {
      this.BellCommand = new RelayCommand(this.ExecuteBell);
      this.LunchCommand = new RelayCommand(this.ExecuteLunch);
   }

   private void ExecuteBell(object Parameter) {...}
   private void ExecuteLunch(object Parameter) {...}
}

and in your XAML

<Button Command="{Binding Path=BellCommand}"... />

<Button Command="{Binding Path=LunchCommand}" ... />

This way you have separate places for the individual logic and your viewmodel must not know anything about your ui - which is good.

Hope it helps.

Upvotes: 2

regisdark
regisdark

Reputation: 19

XAML:

<Button CommandParameter="command_name" Command="{Binding OnClick}" Content="Click Me"></Button>

Event.cs:

using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
       private ICommand onClick;
       public ICommand OnClick
      {
       get
       {
       return onClick ?? (onClick = new RelayCommand(clickSwitch));
       }
    }

Class.cs:

private async void clickSwitch(System.Object obj)
     {
      switch (obj.ToString())
       {
        case "command_name":
        //code
        break;
    }

Upvotes: 0

Related Questions