MVVM 绑定到 CLR 事件 [英] MVVM binding to CLR Events

查看:32
本文介绍了MVVM 绑定到 CLR 事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用 mvvm 模式绑定到 CLR 事件?

How do you go about binding to a CLR event using the mvvm pattern?

对于路由事件,我使用 Cinch 框架中的 EventToCommandTrigger,效果很好.

For routed events I am using the EventToCommandTrigger from Cinch's framework and that is working great.

我查看了 行为和效果Expression Blend Samples 看起来像 DataEventTrigger 是我应该使用的,但该示例有点令人困惑.

I checked out the Behaviors and Effects from the Expression Blend Samples and it looks like the DataEventTrigger is what I should use, but the sample is a little confusing.

我希望 IsVisibleChanged 事件触发我的 IsVisibleChangedCommand.我也不确定需要在 ViewModel 中使用哪些代码来支持这一点.

I want the IsVisibleChanged event to fire my IsVisibleChangedCommand. I am also not sure what code needs to go in the ViewModel to support this.

<i:Interaction.Triggers>

    <i:EventTrigger EventName="SelectedItemChanged">
        <framework:EventToCommandTrigger Command="{Binding SelectedMenuItemChangedCommand}"
                                        CommandParameter="{Binding SelectedValue, ElementName=lstClusters}" />
    </i:EventTrigger>

    <framework:DataEventTrigger EventName="IsVisibleChanged"
                            Source="{Binding IsVisibleChangedCommand}">
    </framework:DataEventTrigger>

</i:Interaction.Triggers>

推荐答案

您可以使用 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
}

无论哪种方式都可以.

这篇关于MVVM 绑定到 CLR 事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆