Mvvm - 如何使用数据绑定命令和参数命令在 ViewModel 中捕获按下了哪个按钮?我没有得到什么?
Mvvm - How to capture in the ViewModel, which Button was pressed, using dataBinding command and Parameter Command? What am I not getting?
为简化起见,一个月前因编写小说 w/no 代码而受到批评,我在 UI 上制作了一个带有 2 个按钮的快速 wpf 项目(使用 MVVM)。
单击按钮时,我需要我的 ViewModel 知道是哪个按钮,以便将语音合成器路由到正确的 Text to Speak。谢谢 4 任何帮助!!
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);
}
}
}
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;
}
在你的视图模型上只有一个命令并将每个按钮绑定到它是一个糟糕的解决方案。如果您有不同的事情要执行,请定义不同的命令。为此,您必须为每个命令定义一个单独的 class 和专用的 Execute
方法,或者您可以使用类似 RelayCommand
或 MvvmLight 的方法,您可以在其中传递委托像这样创建每个命令
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) {...}
}
在你的 XAML
<Button Command="{Binding Path=BellCommand}"... />
<Button Command="{Binding Path=LunchCommand}" ... />
这样您就可以为各个逻辑提供单独的位置,并且您的视图模型必须对您的 ui 一无所知 - 这很好。
希望对您有所帮助。
为简化起见,一个月前因编写小说 w/no 代码而受到批评,我在 UI 上制作了一个带有 2 个按钮的快速 wpf 项目(使用 MVVM)。 单击按钮时,我需要我的 ViewModel 知道是哪个按钮,以便将语音合成器路由到正确的 Text to Speak。谢谢 4 任何帮助!!
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);
}
}
}
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;
}
在你的视图模型上只有一个命令并将每个按钮绑定到它是一个糟糕的解决方案。如果您有不同的事情要执行,请定义不同的命令。为此,您必须为每个命令定义一个单独的 class 和专用的 Execute
方法,或者您可以使用类似 RelayCommand
或 MvvmLight 的方法,您可以在其中传递委托像这样创建每个命令
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) {...}
}
在你的 XAML
<Button Command="{Binding Path=BellCommand}"... />
<Button Command="{Binding Path=LunchCommand}" ... />
这样您就可以为各个逻辑提供单独的位置,并且您的视图模型必须对您的 ui 一无所知 - 这很好。
希望对您有所帮助。