MVVM结合CLR事件 [英] MVVM binding to CLR Events

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

问题描述

你如何去使用MVVM模式绑定到CLR事件?

有关路由事件我使用的是从EventToCommandTrigger莲花的框架和是伟大的工作。

我检查了<一个href=\"http://ex$p$pssionblend.$c$cplex.com/wikipage?title=Behaviors%20and%20Effects&referringTitle=Documentation\"相对=nofollow>行为和效果,从防爆pression混合样品与它看起来像DataEventTrigger是我应该用什么,但样品是有点混乱。

我要IsVisibleChanged在事件激发我的IsVisibleChangedCommand。我也是不知道什么code需要在视图模型去支持这一点。

 &LT; I:Interaction.Triggers&GT;    &LT; I:的EventTrigger事件名称=SelectedItemChanged&GT;
        &LT;框架:EventToCommandTrigger命令={结合SelectedMenuItemChangedCommand}
                                        CommandParameter ={绑定的SelectedValue,的ElementName = lstClusters}/&GT;
    &LT; /我:&的EventTrigger GT;    &LT;框架:DataEventTrigger事件名称=IsVisibleChanged在
                            来源={结合IsVisibleChangedCommand}&GT;
    &LT; /框架:DataEventTrigger&GT;&LT; /我:Interaction.Triggers&GT;


解决方案

您可以使用防爆pression混合SDK为应对一般的事件中调用命令,但是我的经验是,并非所有事情都是由支持的EventTrigger。

例如,这似乎工作:

 &LT;标签内容=LabelText的&GT;
    &LT; I:Interaction.Triggers&GT;
        &LT; I:的EventTrigger事件名称=的MouseMove&GT;
            &LT; I:InvokeCommandAction命令={结合IsVisibleChangedCommand,模式=单向}/&GT;
        &LT; /我:&的EventTrigger GT;
    &LT; /我:Interaction.Triggers&GT;
&LT; /标签&gt;

但是,这并不:

 &LT;标签内容=LabelText的&GT;
    &LT; I:Interaction.Triggers&GT;
        &LT; I:的EventTrigger事件名称=IsVisibleChanged在&GT;
            &LT; I:InvokeCommandAction命令={结合IsVisibleChangedCommand,模式=单向}/&GT;
        &LT; /我:&的EventTrigger GT;
    &LT; /我:Interaction.Triggers&GT;
&LT; /标签&gt;

我不知道为什么,但混合SDK似乎并不喜欢IsVisible属性。你可以做类似的一个PropertyChangedTrigger像这样的东西,但使用可视性(而非可见性):

 &LT;标号x:名称=LABEL1CONTENT =LabelText的&GT;
    &LT; I:Interaction.Triggers&GT;
        &LT; EI:PropertyChangedTrigger绑定={结合能见度,的ElementName = LABEL1}&GT;
            &LT; I:InvokeCommandAction命令={结合IsVisibleChangedCommand,模式=单向}/&GT;
        &LT; / EI:PropertyChangedTrigger&GT;
    &LT; /我:Interaction.Triggers&GT;
&LT; /标签&gt;

顺便说一句 - 这里是命名空间:

 的xmlns:I =htt​​p://schemas.microsoft.com/ex$p$pssion/2010/interactivity
的xmlns:EI =htt​​p://schemas.microsoft.com/ex$p$pssion/2010/interactions

此外,这里是另一种解决您的具体问题,不需要交融SDK:

而不是一个事件直接绑定到一个命令,您可以将对象的可见性属性绑定到视图模型属性,并从属性setter这样执行命令:

查看:

 &LT;用户控件X:类=SampleApp.Views.EventBindingDemoView
             的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
             的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
             高度=200宽度=200&GT;
    &LT; UserControl.Resources&GT;
        &LT; BooleanToVisibilityConverter X:键=BooleanToVisibilityConverter/&GT;
    &LT; /UserControl.Resources>
    &LT;网格和GT;
        &LT;标签内容=LabelText的能见度={绑定路径= ElementIsVisible,模式=双向,转换器= {StaticResource的BooleanToVisibilityConverter}}/&GT;        &LT;! - 视图的其余部分在这里 - &GT;    &LT; /网格和GT;
&LT; /用户控件&GT;

视图模型(ViewModelBase应实现INotifyPropertyChanged和OnPropertyChanged(字符串propertyName的)):

 公共类EventBindingDemoViewModel:ViewModelBase
{
    私人布尔ElementIsVisibleField = TRUE; //还是假的,如果它最初应该被隐藏
    公共BOOL ElementIsVisible
    {
        {返回this.ElementIsVisibleField; }
        组
        {
            如果(this.ElementIsVisibleField!=值)
            {
                this.ElementIsVisibleField =价值;
                this.OnPropertyChanged(ElementIsVisible);                //执行命令
                this.IsVisibleChangedCommand.Execute(NULL);
            }
        }
    }    公众的ICommand IsVisibleChangedCommand;    //您的视图模型在这里休息
}

无论哪种方式应该工作。

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

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

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.

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>

解决方案

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>

But this doesn't:

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

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"

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

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:

View:

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

Either way should work.

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

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