WPF中Style中的EventSetter处理程序绑定

23

我有一个样式,想要将一个命令与EventSetterHandler绑定,并使用RelativeSource。该命令在viewModel中。

<Style x:Key="ItemTextBlockEventSetterStyle" TargetType="{x:Type TextBlock}">
    <EventSetter Event="MouseLeftButtonDown" 
                 Handler="{Binding TextBlockMouseLeftButtonDownCommand, 
                           RelativeSource={RelativeSource Self}}"/>
</Style>

问题是我遇到了错误,因为这个东西有问题(也许不能用这种简单的方式实现)。

之前我已经搜索过很多,发现了AttachedCommandBehaviour,但我认为它不适用于样式。

你能否给一些提示来解决这个问题?

更新13/10/2011

我在MVVM Light Toolkit的EventToCommand示例程序中找到了这个:

        <Button Background="{Binding Brushes.Brush1}"
            Margin="10"
            Style="{StaticResource ButtonStyle}"
            Content="Simple Command"
            Grid.Row="1"
            ToolTipService.ToolTip="Click to activate command">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
                <cmd:EventToCommand Command="{Binding SimpleCommand}" />
            </i:EventTrigger>
            <i:EventTrigger EventName="MouseLeave">
                <cmd:EventToCommand Command="{Binding ResetCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>

但是,在这里,绑定不在样式中。我该如何将EventToCommand应用到按钮的样式中呢?

3个回答

29

目前你将 MouseLeftButtonDown 事件绑定到了 TextBlock.TextBlockMouseLeftButtonDownCommandTextBlockMouseLeftButtonDownCommand 不是 TextBlock 的有效属性,也不像是事件处理程序。

我通常在样式中使用 AttachedCommandBehavior 来将命令与事件关联起来。语法通常类似于这样(请注意 Command 绑定中的 DataContext):

<Style x:Key="ItemTextBlockEventSetterStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="local:CommandBehavior.Event" Value="MouseLeftButtonDown" />
    <Setter Property="local:CommandBehavior.Command"
            Value="{Binding DataContext.TextBlockMouseLeftButtonDownCommand, 
                            RelativeSource={RelativeSource Self}}" />
</Style>

另一种方法是将EventSetter与代码后台中的事件连接,并在那里处理命令:

<Style x:Key="ItemTextBlockEventSetterStyle" TargetType="{x:Type TextBlock}">
    <EventSetter Event="MouseLeftButtonDown" 
                 Handler="TextBlockMouseLeftButtonDown"/>
</Style>

在代码后台中的事件处理程序...

void TextBlockMouseLeftButtonDown(object sender, MouseEventArgs e)
{
    var tb = sender as TextBlock;
    if (tb != null)
    {
        MyViewModel vm = tb.DataContext as MyViewModel;

        if (vm != null && TextBlockMouseLeftButtonDownCommand != null
            && TextBlockMouseLeftButtonDownCommand.CanExecute(null))
        {
            vm.TextBlockMouseLeftButtonDownCommand.Execute(null)
        }
    }
}

把命令执行放到事件中是个好主意,但我明天会尝试使用AttachCommandBehavior!非常感谢你的回答! - Zoltán Barna
AttachCommandBehavior工作得非常完美。但有一件事情我不确定如何解决,我想绑定命令不仅限于一个事件,并找到了这样的解决方案:http://stackoverflow.com/questions/926451/how-can-i-attach-two-attached-behaviors-to-one-xaml-element这个方法非常好,但是我该如何将CommandBehaviorCollection放入样式中呢?感谢您的答复! - Zoltán Barna
@ZoltánBarna 看起来在样式或模板中无法工作。 - Rachel
你好Rachel,非常感谢。我遇到了与OP完全相同的问题,而System.Windows.Interactivity中的<InvokeCommandAction>失败了,但AttachedCommandBehavior却完美地解决了这个问题。 - Golvellius

5

我看到了关于矩形和事件触发器的示例,它可以正常工作,同时也使用了事件设置器? - Zoltán Barna

0

我的回答这个问题是不需要任何外部工具包/库就能解决的。但是,它没有使用RelativeSource,并且也不是100%的MVVM。它需要在代码后台事件处理程序中添加一行代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接