Button.MouseDown [英] Button.MouseDown

查看:148
本文介绍了Button.MouseDown的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对WPF比较陌生. 我试图了解MouseDownEvent和PreviewMouseDownEvent之间的区别.

I'm relatively new with WPF. I'm trying to understand the difference between MouseDownEvent and PreviewMouseDownEvent.

我了解WPF事件策略,并且了解MouseDown事件是冒泡事件,而PreviewMouseDown是隧道事件.

I understand the WPF event strategies and i understand that the MouseDown event is a bubbling event and the PreviewMouseDown is a tunneling event.

我还了解了触发这些事件的顺序-根据此MSDN概述 http://msdn.microsoft.com/zh-cn/library/ms742806.aspx#routing (那里有一个带有示例的图表).

I also understand the order of which these events are being fired - according to this MSDN overview http://msdn.microsoft.com/en-us/library/ms742806.aspx#routing (there is a diagram with example there).

所以我尝试编写一些自己的代码,例如:

So i tried to code some my self, check this for example:

<Grid x:Name="grid" Width="250">
    <StackPanel Mouse.MouseDown="StackPanel_MouseDown" PreviewMouseDown="StackPanel_PreviewMouseDown">
    <WPFVisualizerExample:MyButton x:Name="B1" PreviewMouseDown="B1_PreviewMouseDown" MouseDown="B1_MouseDown" Margin="5,5,5,5">
            <WPFVisualizerExample:MyButton x:Name="B2" PreviewMouseDown="B2_PreviewMouseDown" MouseDown="B2_MouseDown"  Margin="5,5,5,5">
                <WPFVisualizerExample:MyButton x:Name="B3" PreviewMouseDown="B3_PreviewMouseDown" MouseDown="B3_MouseDown"  Margin="5,5,5,5">Click Me</WPFVisualizerExample:MyButton>
            </WPFVisualizerExample:MyButton>
    </WPFVisualizerExample:MyButton>           
    </StackPanel>        
</Grid>

我为每个事件(预览和非预览)都有一个事件处理程序,我想看看发生了什么,正在抛出哪个事件(我为每个事件都显示了一个消息框).

I have an event handler for each of the events (the preview and non-preview) and i wanted to see what is happening, which of the event is being thrown (i have a message box shown for each event).

"MyButton"用户控件只是扩展了基本Button并覆盖了OnMouseDown和OnPreviewMouseDown来将e.Handled设置为false:

The 'MyButton' user control simply extends the base Button and override the OnMouseDown and OnPreviewMouseDown to set the e.Handled false:

    protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
    {            
        base.OnMouseDown(e);
        e.Handled = false;
    }

    protected override void OnPreviewMouseDown(System.Windows.Input.MouseButtonEventArgs e)
    {            
        base.OnPreviewMouseDown(e);
        e.Handled = false;
    }

(尝试使用此方法,也可以不使用此方法).

(tried with this and without this).

根据MSDN概述(在上面的链接中),如果我有3个元素,则事件路由应如下:

According to the MSDN overview (in the link above), if i have 3 elements then the events route should be as follows:

根元素上的PreviewMouseDown(隧道).

PreviewMouseDown (tunnel) on root element.

中间元素#1上的PreviewMouseDown(隧道).

PreviewMouseDown (tunnel) on intermediate element #1.

源元素#2上的PreviewMouseDown(隧道).

PreviewMouseDown (tunnel) on source element #2.

MouseDown(气泡)在源元素2上.

MouseDown (bubble) on source element #2.

MouseDown(气泡)在中间元素#1上.

MouseDown (bubble) on intermediate element #1.

MouseDown(气泡)在根元素上.

MouseDown (bubble) on root element.

因此,我希望根据以上内容显示消息框. 由于某种原因-我不明白,仅引发了预览事件(根据MSDN所说的Preview_B1 => Preview_B2 => Preview_B3). 我的期望是: Preview_B1 => Preview_B2 => Preview_B3 => NonPreview_B3 => NonPreview_B2 => NonPreview_B1.

So I expected the the message boxes to be shown according to the above. From some reason - which I don't understand only the preview events are being thrown (according to what the MSDN says Preview_B1=>Preview_B2=>Preview_B3). My expectations were: Preview_B1=>Preview_B2=>Preview_B3=>NonPreview_B3=>NonPreview_B2=>NonPreview_B1.

但是完全不会引发非预览事件.

But the non-preview events are not being thrown at all.

所以基本上我不了解事件的路由,从MSDN概述中我了解到路由从根元素开始,向下(隧道)到源元素,然后向上(气泡)到根元素,但实际情况并非如此.

So basically I don't understand the route of the events, from MSDN overview I understood that the route starts from the root element, goes down (tunnel) to the source element and then back up (bubble) to the root element, but this is not what happening in practice.

对我来说,了解这些事件的工作方式非常重要,我可能会错过一些基本的知识,您的帮助将不胜感激.

It is really important for me to understand how this events are working, i probably miss-understand something basic here, your help will be appreciated.

谢谢! -吉利

推荐答案

由于Button控件的功能是产生Click事件(或触发命令),因此它对Mouse事件的处理与其他控件略有不同.当Button收到PreviewMouseDown事件时,它将其转换为Click事件,从而取消Preview和MouseDown起泡事件的任何进一步传送.根据Button的ClickMode设置,这会有一些变化.如果您宁愿自己使用Mouse事件,也可以改用ContentControl(尝试一下,您应该会看到预期的结果),但在大多数情况下,您可能会发现使用Button.Click会容易得多.

Since the function of the Button control is to produce a Click event (or fire a Command) it treats the Mouse events a little differently than other controls. When Button receives a PreviewMouseDown event it converts it to a Click event, cancelling any further tunnelling of Preview and the MouseDown bubbling event. There is some variation in this depending on the ClickMode setting of the Button. If you'd rather use the Mouse events themselves you can just use a ContentControl instead (try it and you should see exactly what you expected) but you'll probably find it's much easier to use Button.Click in most cases.

更新

您的代码中肯定还有其他事情正在引起事件路由停止.这是一个与您验证的示例相似的示例,该示例显示了预期的输出(添加了一些样式以使元素显而易见):

There must be something else going on in your code that's causing the event routing to stop. Here's an example similar to yours that I verified that shows expected output (some styling added to make the elements obvious):

<Window.Resources>
    <Style TargetType="{x:Type ContentControl}">
        <Setter Property="BorderThickness" Value="5" />
        <Setter Property="Padding" Value="10" />
        <Setter Property="Background" Value="PaleGreen" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ContentControl}">
                    <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                        <ContentPresenter/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<StackPanel Tag="Panel" PreviewMouseDown="PreviewMouseDown" MouseDown="MouseDown">
    <ContentControl BorderBrush="Red" Tag="C1" PreviewMouseDown="PreviewMouseDown" MouseDown="MouseDown">
        <ContentControl BorderBrush="Green" Tag="C2" PreviewMouseDown="PreviewMouseDown" MouseDown="MouseDown">
            <ContentControl Content="Click Me" BorderBrush="Blue" Tag="C3" PreviewMouseDown="PreviewMouseDown" MouseDown="MouseDown"/>
        </ContentControl>
    </ContentControl>
</StackPanel>

和编写Debug的简单处理程序:

and simple handlers to write to Debug:

private void PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    Debug.WriteLine((sender as FrameworkElement).Tag + " Preview");
}

private void MouseDown(object sender, MouseButtonEventArgs e)
{
    Debug.WriteLine((sender as FrameworkElement).Tag + " Bubble");
}

调试输出(如果单击中心文本)为:

Debug Output (if center text is clicked) is:

面板预览
C1预览
C2预览
C3预览
C3泡泡
C2气泡
C1泡泡
面板气泡

Panel Preview
C1 Preview
C2 Preview
C3 Preview
C3 Bubble
C2 Bubble
C1 Bubble
Panel Bubble

这篇关于Button.MouseDown的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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