在使用WPF的ICommand接口时,例如按钮的Command属性可以绑定ViewModel中的一条命令,并可向其中传递参数,通常只能通过CommandParameter属性传递一个object类型的参数。如果需要传入多个参数到ViewModel的命令中,又该如何实现呢?
第一步,创建一个子类,继承ICommand接口,或者安装mvvmlight、communityToolkit.mvvm等框架。
public class RelayCommand<T> : ICommand
{
public event EventHandler CanExecuteChanged;
public Action<T> Action { get; }
public RelayCommand(Action<T> action)
{
Action = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
Action?.Invoke((T)parameter);
}
}
第二步,创建一个MainViewModel,在其中定义一个带参数的命令。
public class MainViewModel
{
public ICommand SubmitCommand { get; }
public MainViewModel()
{
SubmitCommand = new RelayCommand<object>(OnSubmitCommand);
}
private void OnSubmitCommand(object obj)
{
string content = string.Empty;
if(obj is Object[] array)
{
foreach(var item in array)
{
if(item is TextBlock textBlock)
{
content += textBlock.Text + "\r\n";
}
}
}
MessageBox.Show(content);
}
}
第三步,创建一个多值转换器,因为多值转换器可以绑定多个XAML上的控件或控件属性
internal class MultiValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values.ToArray();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
第四步,在窗体的Resources属性中实例化MultiValueConverter ,然后在界面上创建几个TextBlock和Button,Button的Command绑定到SubmitCommand ,Button的CommandParameter属性则实例化一个MultiBinding对象 ,将4个TextBlock控件绑定到MultiBinding对象,最后由MultiValueConverter转换器转换成一个数组对象传入ViewModel中。
<Window x:Class="HelloWorld.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:HelloWorld"
xmlns:forms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:viewmodels="clr-namespace:HelloWorld.ViewModels"
mc:Ignorable="d" FontSize="14"
Title="WPF中文网之数据绑定-多参数传递 - www.wpfsoft.com" Height="350" Width="500">
<Window.DataContext>
<viewmodels:MainViewModel/>
</Window.DataContext>
<Window.Resources>
<viewmodels:MultiValueConverter x:Key="MultiValueConverter"/>
</Window.Resources>
<StackPanel x:Name="panel" VerticalAlignment="Center" Margin="80,0">
<TextBlock x:Name="textblock1" Margin="5" Text="床前明月光"/>
<TextBlock x:Name="textblock2" Margin="5" Text="疑是地上霜"/>
<TextBlock x:Name="textblock3" Margin="5" Text="举头望明月"/>
<TextBlock x:Name="textblock4" Margin="5" Text="低头思故乡"/>
<Rectangle Height="15"/>
<Button Content="传递多个参数" Command="{Binding SubmitCommand}" >
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource MultiValueConverter}">
<MultiBinding.Bindings>
<Binding ElementName="textblock1"/>
<Binding ElementName="textblock2"/>
<Binding ElementName="textblock3"/>
<Binding ElementName="textblock4"/>
</MultiBinding.Bindings>
</MultiBinding>
</Button.CommandParameter>
</Button>
</StackPanel>
</Window>
如图所示,最终将在ViewModel中接收4个TextBlock控件,并把内容连接成一首完整的诗。这个示例中的MultiValueConverter转换器和MultiBinding多值绑定器是一个桥梁,将多个控件接收后,形成一个对象传入ViewModel中,本质上,还是只传了一个对象,只不过这个对象是一个数组。
当前课程源码下载:(注明:本站所有源代码请按标题搜索)
文件名:20240710-WPF利用CommandParameter属性传入多个参数至ViewModel.zip
链接:https://pan.baidu.com/s/1yu-q4tUtl0poLVgmcMfgBA
提取码:wpff