Reputation: 25
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!!
<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
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
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