且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

MVVM 绑定到 CLR 事件

更新时间:2022-05-20 02:57:27

您可以使用 Expression Blend SDK 来调用命令来响应一般事件,但我的经验是 EventTrigger 并不支持所有事件.

You can use the Expression Blend SDK for invoking commands in response to events in general, however my experience has been that not all events are supported by EventTrigger.

>

例如,这似乎有效:

For example, this seems to work:

<Label Content="LabelText">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseMove">
            <i:InvokeCommandAction Command="{Binding IsVisibleChangedCommand, Mode=OneWay}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Label>

但这不会:

<Label Content="LabelText">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="IsVisibleChanged">
            <i:InvokeCommandAction Command="{Binding IsVisibleChangedCommand, Mode=OneWay}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Label>

我不知道为什么,但 Blend SDK 似乎不喜欢 IsVisible 属性.您可以执行类似的操作,但将 Visibility(而不是 IsVisible)与 PropertyChangedTrigger 一起使用,如下所示:

I'm not sure why, but Blend SDK does not seem to like the IsVisible property. You can do something similar but using Visibility (instead of IsVisible) with a PropertyChangedTrigger like this:

<Label x:Name="label1" Content="LabelText">
    <i:Interaction.Triggers>
        <ei:PropertyChangedTrigger Binding="{Binding Visibility, ElementName=label1}">
            <i:InvokeCommandAction Command="{Binding IsVisibleChangedCommand, Mode=OneWay}"/>
        </ei:PropertyChangedTrigger>
    </i:Interaction.Triggers>
</Label>

顺便说一句 - 以下是命名空间:

BTW - Here are the namespaces:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

此外,这里是针对您的特定问题的另一种解决方案,不需要 Blend SDK:

Also, here is another solution to your specific problem that does not require the Blend SDK:

不是直接将事件绑定到命令,您可以将对象的 Visibility 属性绑定到视图模型属性,然后从属性设置器执行命令,如下所示:

Instead of directly binding an event to a command, you can bind the Visibility property of your object to a viewmodel property and execute the command from the property setter like this:

查看:

<UserControl x:Class="SampleApp.Views.EventBindingDemoView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Height="200" Width="200">
    <UserControl.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
    </UserControl.Resources>
    <Grid>
        <Label Content="LabelText" Visibility="{Binding Path=ElementIsVisible, Mode=TwoWay, Converter={StaticResource BooleanToVisibilityConverter}}"/>

        <!-- The rest of your view here -->

    </Grid>
</UserControl>

ViewModel(ViewModelBase 应该实现 INotifyPropertyChanged 和 OnPropertyChanged(string propertyName)):

ViewModel (ViewModelBase should implement INotifyPropertyChanged and OnPropertyChanged(string propertyName) ):

public class EventBindingDemoViewModel : ViewModelBase
{
    private bool ElementIsVisibleField = true; // or false if it should initially be hidden
    public bool ElementIsVisible
    {
        get { return this.ElementIsVisibleField; }
        set
        {
            if (this.ElementIsVisibleField != value)
            {
                this.ElementIsVisibleField = value;
                this.OnPropertyChanged("ElementIsVisible");

                // Execute command
                this.IsVisibleChangedCommand.Execute(null);
            }
        }
    }

    public ICommand IsVisibleChangedCommand;

    // The rest of your viewmodel here
}

无论哪种方式都可以.