mvvm模式 事件觸發器[wpf]

小林野夫發表於2024-03-18

還有另一種方法可以將檢視中的控制元件與檢視模型公開的命令物件相關聯。實際上,只有某些控制元件可以透過 Command 屬性繫結到命令,特別是派生自 System.Windows.Controls.Primitives.ButtonBaseSystem.Windows.Controls.MenuItem 的控制元件。如果要將命令附加到某個其他控制元件,或者要對按鈕的單擊事件以外的事件呼叫命令,則可以使用 Expression Blend 互動觸發器和 System.Windows.Interactivity.InvokeCommandAction 類。下面是一個示例,說明當使用者將滑鼠指標移到檢視中的 Rectangle 元素上時,如何在檢視模型中執行名為 MouseEnterCommand 的命令物件。在 EventTrigger 的 EventName 屬性中指定將為其執行命令的事件。請記住新增對 System.Windows.Interactivity.dll 的引用,以便進行編譯。
另請注意,使用 InvokeCommandAction 不會基於命令的 CanExecute 方法自動啟用或禁用控制元件,這與具有 Command 屬性且可直接繫結到命令的控制元件不同。

<Window x:Class="Mm.HandlingEventsMVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <Rectangle Fill="Yellow" Stroke="Black" Width="100" Height="100">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter" >
                    <i:InvokeCommandAction Command="{Binding MouseEnterCommand}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Rectangle>
    </StackPanel>
</Window>

命令引數

如果希望將引數從檢視傳遞給命令,請使用 CommandParameter 屬性來實現。泛型 DelegateCommand<T> 類的型別引數指定傳遞給 Execute 和 CanExecute 方法的命令引數的型別。CommandParameter 屬性存在於 ButtonBaseMenuItem 派生控制元件以及 InvokeCommandAction 類中:


<Button Content="Click here!" Command="{Binding ButtonClickCommand}"
                CommandParameter="some string to be passed..."
                Margin="0 5 0 0"/>
<i:InvokeCommandAction Command="{Binding MouseEnterCommand}"
                       CommandParameter="some string to be passed..."/>

CallMethodAction

除了 InvokeCommandAction 類之外,還有另一個名為 CallMethodAction 的類,可用於在不使用命令的情況下從檢視呼叫檢視模型中的方法。它有一個 MethodName 屬性,用於指定要呼叫的方法的名稱,還有一個 TargetObject 屬性,該屬性需要繫結到包含該方法的類的例項,即檢視模型:

<Window x:Class="Mm.HandlingEventsMVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <Rectangle Fill="Yellow" Stroke="Black" Width="100" Height="100">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter" >
                    <!-- Execute a method called 'SomeMethod' defined in the view model -->
                    <ei:CallMethodAction TargetObject="{Binding}" MethodName="SomeMethod"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Rectangle>
    </StackPanel>
</Window>
public void  SomeMethod()
{
    /* do something ... */
}

請注意,CallMethodAction 類在另一個程式集和名稱空間中定義,您需要新增對 Microsoft.Expressions.Interactions.dll 的引用才能使用它。另請注意,它不支援引數。

相關文章