WPF入门到跪下 第九章 MVVM-用命令触发行为

发布时间:2024年01月14日

MVVM模式下的命令触发行为

上文中对命令的使用都是直接通过控件中的Command属性来进行绑定的,默认情况下,Command属性所绑定的命令,其触发条件是鼠标的点击。

接下来学习如何使用其他行为来作为命令的触发条件。

一、鼠标输入的命令绑定

LeftClick:单击鼠标左键。

LeftDoubleClick:双击鼠标左键。

MiddleClick:单击鼠标中键。

MiddleDoubleClick:双击鼠标中键。

RightClick:单击鼠标右键。

RightDoubleClick:双击鼠标右键。

None:不执行任何操作。

WheelClick:旋转鼠标滚轮。

要将鼠标的其他行为来作为命令的触发条件,需要使用控件的InputBindings属性,并在其中添加MouseBinding对象。

<Window.CommandBindings>
    <CommandBinding Command="ApplicationCommands.Open" Executed="Button_Executed" CanExecute="Button_CanExecute"/>
</Window.CommandBindings>
<Grid>
    <StackPanel>
        <Button Content="MouseDoubleClick">
            <Button.InputBindings>
                <MouseBinding MouseAction="LeftDoubleClick" 
                              Command="ApplicationCommands.Open"/>
            </Button.InputBindings>
        </Button>
    </StackPanel>
</Grid>

二、键盘输入的命令绑定

要将键盘的行为作为命令的触发条件,需要使用控件的InputBindings属性,并在其中添加KeyBinding对象。

<Window.CommandBindings>
    <CommandBinding Command="ApplicationCommands.Open" Executed="Button_Executed" CanExecute="Button_CanExecute"/>
</Window.CommandBindings>
<Grid>
    <StackPanel>
        <Button Content="Alt+K">
            <Button.InputBindings>
                <KeyBinding Key="K" Modifiers="Alt"
                            Command="ApplicationCommands.Open"/>
            </Button.InputBindings>
        </Button>
    </StackPanel>
</Grid>

用的时候发现,如果控件对象是个按钮,要先点击一下按钮,将焦点聚焦到按钮上,按键盘才有用。可能还有其他解决方案,基本上用不上,暂时不研究了。

三、任意事件的绑定

进行任意事件的绑定处理前,先通过Nuget安装Microsoft.Xaml.Behaviors.Wpf库。
在这里插入图片描述

1、任意事件绑定命令

Command层

public class MyCommand : ICommand
{
    //这里为了方便就不去调用检查事件了
    public event EventHandler CanExecuteChanged;

    public Func<object,bool> DoCanExecute{ get; set; }
    public bool CanExecute(object parameter)
    {
        return DoCanExecute(parameter) == true;
    }

    public Action<object> DoExecute { get; set; }
    public void Execute(object parameter)
    {
        DoExecute(parameter);
    }
}

Model层

public class MainModel
{
    public MyCommand MyCommand { get; set; }
    public MainModel()
    {
        MyCommand = new MyCommand
        {
            DoExecute = DoExecute,
            DoCanExecute = DoCanExecute
        };
    }

    private void DoExecute(object obj)
    {
        Debug.WriteLine("执行命令");
    }
    private bool DoCanExecute(object obj)
    {
        Debug.WriteLine("判断是否可执行命令");
        return true;
    }

}

ViewModel层

public class MainViewModel
{
    public MainModel MainModel { get; set; } = new MainModel();
}

XAML

<Window ......
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        ......>
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Grid>
        <StackPanel>
            <ComboBox>
           		<!--进行命令绑定-->
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="SelectionChanged">
                        <i:InvokeCommandAction Command="{Binding MainModel.MyCommand}" CommandParameter="123"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
                <ComboBoxItem Content="AAA"/>
                <ComboBoxItem Content="BBB"/>
                <ComboBoxItem Content="CCC"/>
            </ComboBox>
        </StackPanel>
    </Grid>
</Window>

如果希望在触发命令时,将事件的参数传递过去,可以设置属性PassEventArgsToCommand="True",例如<i:InvokeCommandAction Command="{Binding MainModel.MyCommand}" PassEventArgsToCommand="True"/>,如果PassEventArgsToCommandCommandParameter同时存在,优先使用CommandParameter

尽管可以传递事件的参数,但是却无法像原生的事件方法那样将触发事件的控件对象也一起传递回去,如果需要达到这样的效果,可以考虑直接绑定到方法上(下文中的方法)。

2、任意事件绑定方法

除了绑定命令对象外,还可以直接绑定到方法上,其方法签名中的参数列表与原生的事件处理方法的相同。

ViewModel层

关于对应函数的签名,可以通过控件的对应事件处理函数自动生成后复制出来

public class MainViewModel
{
    ......

    public void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        //这里可以获取到控件对象,进行业务处理
    }
		
		.....
}

XAML

<Window ......
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        ......>
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Grid>
        <ComboBox>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:CallMethodAction TargetObject="{Binding}" MethodName="ComboBox_SelectionChanged"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <ComboBoxItem Content="AAA"/>
            <ComboBoxItem Content="BBB"/>
            <ComboBoxItem Content="CCC"/>
        </ComboBox>
    </Grid>
</Window>

3、综合使用

可以同时使用绑定命令和绑定方法。

XAML

<Window ......
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        ......>
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Grid>
        <ComboBox>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:CallMethodAction TargetObject="{Binding}" MethodName="ComboBox_SelectionChanged"/>
									  <i:InvokeCommandAction Command="{Binding MainModel.MyCommand}" CommandParameter="123"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <ComboBoxItem Content="AAA"/>
            <ComboBoxItem Content="BBB"/>
            <ComboBoxItem Content="CCC"/>
        </ComboBox>
    </Grid>
</Window>
文章来源:https://blog.csdn.net/jjailsa/article/details/135582317
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。