WPF中文网

WPF利用CommandParameter属性传入多个参数至ViewModel

在使用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

copyright @重庆教主 WPF中文网 联系站长:(QQ)23611316 (微信)movieclip (QQ群).NET小白课堂:864486030 | 本文由WPF中文网原创发布,谢绝转载 渝ICP备2023009518号-1