You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI 3中如何通过按钮一次性传递多个控件的值至RelayCommand

WinUI 3中如何通过按钮一次性传递多个控件的值至RelayCommand

嘿,我来帮你解决这个WinUI 3里的小问题!你想通过按钮一次性把两个TextBox的值传给RelayCommand,其实有几个实用的方案,我给你挨个说清楚:

1. MVVM属性绑定(最推荐,符合规范)

其实在MVVM模式下,我们完全不用纠结CommandParameter的单参数限制——因为根本不需要传参数!我们可以直接把TextBox的文本和ViewModel里的属性做双向绑定,按钮的Command执行时直接取ViewModel里的属性值就行。

第一步:修改XAML,绑定ViewModel属性

把两个TextBox的Text属性和你ViewModel里的FirstName、LastName做双向绑定:

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="First Name"/>
        <TextBox Header="First Name" Text="{x:Bind ViewModel.FirstName, Mode=TwoWay}" />
    </StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="Last Name"/>
        <TextBox Header="Last Name" Text="{x:Bind ViewModel.LastName, Mode=TwoWay}" />
    </StackPanel>
    <Button Content="Save" Command="{x:Bind ViewModel.SaveCommand}" />
</StackPanel>

第二步:在ViewModel里实现属性和Command

假设你用的是CommunityToolkit.Mvvm(WinUI里常用的MVVM工具包),ViewModel可以这么写:

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

public class YourViewModel : ObservableObject
{
    // 定义和TextBox绑定的FirstName属性
    private string _firstName;
    public string FirstName
    {
        get => _firstName;
        set => SetProperty(ref _firstName, value);
    }

    // 定义和TextBox绑定的LastName属性
    private string _lastName;
    public string LastName
    {
        get => _lastName;
        set => SetProperty(ref _lastName, value);
    }

    // 定义SaveCommand
    public IRelayCommand SaveCommand { get; }

    public YourViewModel()
    {
        SaveCommand = new RelayCommand(ExecuteSave);
    }

    // Command的执行方法,直接取属性值
    private void ExecuteSave()
    {
        string firstName = FirstName;
        string lastName = LastName;
        // 这里直接用这两个值执行你的SQLite插入操作就行啦
    }
}

这种方式完全符合MVVM的“UI和业务逻辑分离”思想,代码也更干净好维护,是最推荐的做法。

2. 用CommandParameter传递打包对象

如果你暂时不想改绑定逻辑,也可以把两个TextBox的值打包成一个对象,通过CommandParameter传过去。

方案A:传递匿名对象(快速实现)

直接在XAML里用{x:Bind}创建匿名对象,把两个文本框的值塞进去:

<StackPanel x:Name="RootPanel" Orientation="Horizontal" HorizontalAlignment="Right">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="First Name"/>
        <TextBox x:Name="firstNameBox" Header="First Name" />
    </StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="Last Name"/>
        <TextBox x:Name="lastNameBox" Header="Last Name" />
    </StackPanel>
    <Button Content="Save" 
            Command="{x:Bind ViewModel.SaveCommand}"
            CommandParameter="{x:Bind new { FirstName = firstNameBox.Text, LastName = lastNameBox.Text }, Mode=OneWay}" />
</StackPanel>

然后ViewModel里的RelayCommand要接收object类型参数,用dynamic来解析:

public IRelayCommand<object> SaveCommand { get; }

public YourViewModel()
{
    SaveCommand = new RelayCommand<object>(ExecuteSave);
}

private void ExecuteSave(object parameter)
{
    if (parameter is dynamic param)
    {
        string firstName = param.FirstName;
        string lastName = param.LastName;
        // 执行SQLite操作
    }
}

方案B:传递强类型对象(更安全)

为了避免dynamic的类型不安全问题,我们可以先定义一个简单的类来存这两个值:

public class PersonInfo
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

然后XAML里的CommandParameter改成创建这个类的实例:

CommandParameter="{x:Bind new PersonInfo { FirstName = firstNameBox.Text, LastName = lastNameBox.Text }, Mode=OneWay}"

ViewModel里的RelayCommand就可以直接接收PersonInfo类型:

public IRelayCommand<PersonInfo> SaveCommand { get; }

public YourViewModel()
{
    SaveCommand = new RelayCommand<PersonInfo>(ExecuteSave);
}

private void ExecuteSave(PersonInfo info)
{
    if (info != null)
    {
        string firstName = info.FirstName;
        string lastName = info.LastName;
        // 执行SQLite操作
    }
}

3. 后台代码直接获取(适合简单非MVVM场景)

如果你没在用MVVM,只是想快速实现功能,那直接给按钮加Click事件,在后台代码里直接拿两个TextBox的文本就行:

<Button Content="Save" Click="SaveButton_Click" />

后台代码:

private void SaveButton_Click(object sender, RoutedEventArgs e)
{
    string firstName = firstNameBox.Text;
    string lastName = lastNameBox.Text;
    // 执行你的SQLite插入操作
}

不过这种方式就和RelayCommand无关了,适合小型简单的页面,大型项目还是推荐用MVVM的方式。

总的来说,最推荐第一种MVVM属性绑定的方案,既规范又好维护;如果是临时需求,第二种传递打包对象的方式也能快速解决问题。

备注:内容来源于stack exchange,提问作者Nuvolari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 11:54:54