您可以向任何元素添加以下行为,以便它使用正常的按钮逻辑触发ButtonBase.Click
事件:
public class ClickBehavior : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
AssociatedObject.MouseLeftButtonDown += (s, e) =>
{
e.Handled = true;
AssociatedObject.CaptureMouse();
};
AssociatedObject.MouseLeftButtonUp += (s, e) =>
{
if (!AssociatedObject.IsMouseCaptured) return;
e.Handled = true;
AssociatedObject.ReleaseMouseCapture();
if (AssociatedObject.InputHitTest(e.GetPosition(AssociatedObject)) != null)
AssociatedObject.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
};
}
}
注意鼠标捕获/释放和输入命中测试检查的使用。有了这个行为,我们可以编写如下的点击处理程序:
<Grid>
<Rectangle Width="100" Height="100" Fill="LightGreen" ButtonBase.Click="Rectangle_Click">
<i:Interaction.Behaviors>
<utils:ClickBehavior/>
</i:Interaction.Behaviors>
</Rectangle>
</Grid>
代码如下:
private void Rectangle_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Code-behind: Click");
}
将这段代码全部转换为代码后很容易实现;重要的部分是捕获和点击逻辑。
如果您不熟悉行为(behaviors),请安装Expression Blend 4 SDK并添加此命名空间:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
并将System.Windows.Interactivity
添加到您的项目中。
编辑:
以下是如何在代码后台将点击行为附加到元素并添加单击事件处理程序:
void AttachClickBehaviors()
{
AttachClickBehavior(rectangle1, new RoutedEventHandler(OnAttachedClick));
}
void OnAttachedClick(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Attached: Click");
}
static void AttachClickBehavior(FrameworkElement element, RoutedEventHandler clickHandler)
{
Interaction.GetBehaviors(element).Add(new ClickBehavior());
element.AddHandler(ButtonBase.ClickEvent, clickHandler);
}
Label
将放置在模板中的ContentPresenter
处。由于Label
不是在模板内部的,所以您应该可以轻松引用它。除非您只想设置“文本”,否则不要将TextBlock
放入模板中,然后您可以使用Text = "{TemplateBinding Content}"
,然后您将所有设置为按钮内容的内容最终都出现在TextBlock
中(这可能会导致非文本异常;只需使用ContentPresenter
,它会自动绑定到Content
并为文本创建TextBlock
)。 - H.B.