处理XAML中的Button's Click事件
本文关键字:Click 事件 XAML 中的 Button 处理 | 更新日期: 2023-09-27 18:06:16
这感觉像是一个非常基本的问题,但我相信有更好的方法来做到这一点。我在我的UI中有一个Button
,它选择一个特定的选项卡,并从ViewModel
Command
下面是当前代码(工作正常):
XAML:<Button Content="Button!" Click="OnButtonClick" Command="{Binding WhateverCommand}" />
背后的代码:
private void OnButtonClick(object sender, RoutedEventArgs e)
{
theTab.IsSelected = true;
}
有没有更干净的,只有xml的方式来做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'.
谢谢!
编辑因为我问我的窗口的XAML结构,它看起来像这样:
<DockPanel LastChildFill="True">
<Ribbon DockPanel.Dock="Top">
<Button Content="Button!" Click="OnButtonClick" Command="{Binding WhateverCommand}" />
</Ribbon>
<TabControl>
<TabItem x:Name="theTab" />
</TabControl>
</DockPanel>
Error总结。不能在EventTrigger
中使用Setter
。如果你想在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>
肯定有更好的办法。在Windows.Interactivity
程序集的帮助下,您可以将事件源绑定到单个类,仅包含关联的操作。有了这个,你几乎可以做你需要的一切。
动作类必须从TriggerAction派生。通过重写Invoke
-方法,您可以指定操作。
除了这种情况,还可以将EventTrigger
绑定到命令(例如中继命令),从而允许干净的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
您可以将bool
属性IsMyTabSelected
引入您的VM,将其绑定到TabItem.IsSelected
:
<TabItem x:Name="theTab" IsSelected="{Binding IsMyTabSelected}" >
然后您只需在Button
的WhateverCommand
处理程序中设置此标志。注意:IsMyTabSelected
属性必须实现System.ComponentModel.INotifyPropertyChanged
。