如何使用 mvvm 模式绑定(bind)到 CLR 事件?
对于路由事件,我使用 Cinch 框架中的 EventToCommandTrigger,效果很好。
我查看了Behaviors and Effects从 Expression Blend 示例中,看起来 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>
最佳答案
您可以使用 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 属性。您可以执行类似的操作,但使用带有 PropertyChangedTrigger 的 Visibility(而不是 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>
顺便说一句 - 这里是命名空间:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
此外,这是另一个不需要 Blend SDK 的特定问题的解决方案:
您可以将对象的 Visibility 属性绑定(bind)到 viewmodel 属性并从属性 setter 执行命令,而不是直接将事件绑定(bind)到命令,如下所示:
看法:
<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
}
无论哪种方式都应该有效。
关于events - MVVM 绑定(bind)到 CLR 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6497449/