2011-06-27 201 views
4

如何使用mvvm模式綁定到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> 

回答

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> 

我不知道爲什麼,但摻合物SDK似乎並不喜歡的IsVisible屬性。你可以做類似的與PropertyChangedTrigger的東西,但使用可視性(而不是ISVISIBLE)是這樣的:

<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屬性,然後執行屬性設置器中的命令,如下所示:

查看:

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

視圖模型(ViewModelBase應執行INotifyPropertyChanged和OnPropertyChanged(字符串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 
} 

無論哪種方式應該工作。

+0

神祕解決! IsVisibleChanged是一個CLR事件,而不是路由事件。 Blend SDK EventTrigger僅適用於路由事件。 –

+0

從DataEventTrigger上的摘要標記中,它會說:「觸發器,當一個** CLR事件引發時觸發**可用於從數據上下文事件中觸發,而不是在標準事件觸發器上使用路由事件FrameworkElements「。也許我會在他們的討論板上發佈一條消息。 – kevin

+2

請注意,IsVisible和Visibility並不一定是同一件事:「確定IsVisible值將所有佈局因素考慮在內。相比之下,Visibility是一個可設置的屬性,僅表示用編程方式使元素可見或無形。」 – Gusdor