在XAML中处理按钮的Click事件? [英] Handling a Button's Click event in XAML?

查看:345
本文介绍了在XAML中处理按钮的Click事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这听起来像是一个非常基本的问题,但是我相信有更好的方法可以做到这一点。我的UI中有一个按钮,它选择一个特定的选项卡并从中触发一个 Command ViewModel

This feels like a terribly basic question but I am sure there is a better way to do this. I have a Button in my UI which selects a specific tab and fire a Command from the ViewModel

这是当前代码(可以正常工作):

Here is the current code (which works fine):

XAML :

<Button Content="Button!" Click="OnButtonClick" Command="{Binding WhateverCommand}" />

后面的代码:

private void OnButtonClick(object sender, RoutedEventArgs e)
{
     theTab.IsSelected = true;
}

没有任何更干净的,仅限XAML的方法来执行该UI操作?我在想类似的东西:

Isn't there any cleaner, XAML-only way to do that UI operation? I was thinking about something like:

<Button Content="Button!" Click="OnButtonClick" Command="{Binding WhateverCommand}">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Click">
            <Setter TargetName="theTab" Property="IsSelected" Value="True" />
        </EventTrigger>
    </Button.Trigger>
</Button>

但不幸的是,似乎赢得了 EventTrigger 不支持 Click 事件。为什么这样?在WPF工作了几年后,我有时仍然对触发器感到困惑,这几乎可以总结一下。尝试构建时,在 Setter 行上有错误:

But unfortunately it seems like the EventTrigger won't support a Click event. Why so? I am still sometimes confused with triggers after a few years working in WPF, and this pretty much sums it up. When trying to build that I have an error on the Setter line:

A value of type 'Setter' cannot be added to a collection or dictionary of type 'TriggerActionCollection'.

谢谢!

编辑,因为我被问到我的Window的XAML结构,所以它看起来像这样:

EDIT since I was ask the XAML structure of my Window, it looks like this:

<DockPanel LastChildFill="True">
    <Ribbon DockPanel.Dock="Top">
        <Button Content="Button!" Click="OnButtonClick" Command="{Binding WhateverCommand}" />
    </Ribbon>
    <TabControl>
        <TabItem x:Name="theTab" />
    </TabControl>
</DockPanel>


推荐答案

肯定有更好的方法。借助 Windows.Interactivity 程序集,您可以将事件源绑定到仅包含相关动作的单一类。这样,您几乎可以完成您需要的所有工作。

There definitely is a better way. With the help of the Windows.Interactivity assembly you are able to bind the event source to a singe class, containing only the associated action. With this you can almost do everything you ned.

动作类必须从TriggerAction派生。通过覆盖 Invoke 方法,您可以指定操作。

The action class has to derive from TriggerAction. By overriding the Invoke-method you can specify the action.

尽管在这种情况下,也可以将 EventTrigger 绑定到命令(例如中继命令),从而进行清理MMVM实现。

Despite this scenario it also possible to bind the EventTrigger to a command (e.g. relay command), allowing a clean MMVM implementation.

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

<Button x:Name="button">
                        <i:Interaction.Triggers>
                            <i:EventTrigger SourceName="button" EventName="Click">
                                <app:MyAction/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Button>



Public Class MyAction
    Inherits Interactivity.TriggerAction(Of UIElement)

    Protected Overrides Sub Invoke(parameter As Object)
        MsgBox("Clicked")
    End Sub

End Class

我更新了代码以满足您的特定要求。 TriggerAction 类现在还包含一个依赖项属性,可以将其显示在选项卡控件中:

I updated the code to meet your specific requirements. The TriggerAction class now also contains a dependency property, which can be cound to your tab control:

<TabControl x:Name="tab"/>
                    <Button x:Name="button">
                        <i:Interaction.Triggers>
                            <i:EventTrigger SourceName="button" EventName="Click">
                                <app:MyAction Target="{Binding ElementName=tab}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Button>



Public Class MyAction
    Inherits Interactivity.TriggerAction(Of UIElement)

    Protected Overrides Sub Invoke(parameter As Object)
        DirectCast(Target, TabControl).SelectedIndex = 0
    End Sub

    Shared Sub New()
        _targetProperty = DependencyProperty.Register(
          "Target",
          GetType(UIElement),
          GetType(MyAction),
          New UIPropertyMetadata(Nothing))
    End Sub

    Private Shared _targetProperty As DependencyProperty
    Public Shared ReadOnly Property TargetProperty As DependencyProperty
        Get
            Return _targetProperty
        End Get
    End Property

    Property Target As UIElement
        Get
            Return DirectCast(GetValue(TargetProperty), UIElement)
        End Get
        Set(value As UIElement)
            SetValue(TargetProperty, value)
        End Set
    End Property

End Class

这篇关于在XAML中处理按钮的Click事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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