在XAML中处理Button的Click事件?

时间:2014-06-03 09:41:51

标签: c# wpf xaml

这感觉就像一个非常基本的问题,但我相信有更好的方法来做到这一点。我的用户界面中有Button,用于选择特定标签并从Command点击ViewModel

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

XAML:

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

代码背后:

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

是否有任何更清洁,仅限XAML的方式来执行该UI操作?我在考虑类似的事情:

<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行上有错误:

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

谢谢!

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

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

3 个答案:

答案 0 :(得分:9)

错误总结了它。您无法在Setter中使用EventTrigger。如果您想在XAML中执行此操作,可以使用Storyboard按下按钮时选择给定选项卡。像这样:

<Button Content="Click">
   <Button.Triggers>
       <EventTrigger RoutedEvent="Button.Click">
           <BeginStoryboard>
               <Storyboard>
                   <BooleanAnimationUsingKeyFrames Storyboard.TargetName="theTab" Storyboard.TargetProperty="IsSelected">
                       <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
                   </BooleanAnimationUsingKeyFrames>
               </Storyboard>
           </BeginStoryboard>
       </EventTrigger>
   </Button.Triggers>
</Button>

答案 1 :(得分:4)

您可以向VM引入bool属性IsMyTabSelected,将其绑定到TabItem.IsSelected

<TabItem x:Name="theTab" IsSelected="{Binding IsMyTabSelected}" >

然后,您只需在WhateverCommand的{​​{1}}处理程序中设置此标记即可。 注意:Button属性必须实现IsMyTabSelected

答案 2 :(得分:4)

肯定有更好的方法。在Windows.Interactivity程序集的帮助下,您可以将事件源绑定到单个类,仅包含关联的操作。有了这个,你几乎可以做你想要的一切。

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

尽管有这种情况,也可以将EventTrigger绑定到命令(例如relay命令),从而实现干净的MMVM实现。

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类现在还包含一个依赖项属性,可以使用选项卡控件:

<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