MVVM绑定到CLR事件

时间:2011-06-27 18:47:33

标签: events mvvm binding clr

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

对于路由事件,我正在使用Cinch框架中的EventToCommandTrigger,这很有用。

我从Expression Blend Samples中查看了Behaviors and Effects,看起来我应该使用DataEventTrigger,但样本有点令人困惑。

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

<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>

1 个答案:

答案 0 :(得分:7)

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

例如,这似乎有效:

<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,如下所示:

<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 - 以下是命名空间:

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

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

不是直接将事件绑定到命令,而是可以将对象的Visibility属性绑定到viewmodel属性,并从属性setter执行命令,如下所示:

查看:

<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)):

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
}

无论哪种方式都应该有效。