WPF鼠标按下事件

3
我有一个视觉树,它看起来像这样:
一个包含 ScrollViewer 的 Border,其中包含 TextBlock。
ScrollViewer 占据 Border 的 100% 空间,而 TextBlock 可能会或可能不会占据 ScrollViewer 的 100% 空间,这取决于用户如何配置它。
我想捕获当用户在 Border 中的任何位置点击时发生的 MouseDown 事件。当我为 Border 或 ScrollViewer 注册 MouseDown 事件时,回调函数不会被调用。当我将 MouseDown 事件注册到 TextBlock 上时,回调确实被调用,但当然只在 TextBlock 的可点击区域内而不是整个 Border 区域中。
我想到的一个主意是创建某种顶层元素,覆盖整个控件,将其可见性设置为隐藏,然后从那里获取 MouseDown。
有什么建议吗?如果此问题有什么不清楚的地方,请告诉我,我会进行修正。
按请求显示示例代码
// Need to know when a user clicks on anything inside of the border, but the 
// because there are items above it, the mouse event doesn't get invoked.
Border border = new Border();
ScrollViewer viewer = new ScrollViewer();
TextBlock textBlock = new TextBlock();

border.Content = viewer;
viewer.Child = textBlock;

你能否展示一些代码? - Flat Eric
@FlatEric,这段代码太复杂了,无法在一页中展示。正如我所暗示的,这是一个用户可配置应用程序的一部分,因此它非常动态和抽象。我也没有使用XAML。我能做的最好的事情就是创建一些更简单的代码来展示,并且这与我所说的是相同的东西。 - Ay Rue
没人想让您发布整个代码。您需要将问题简化为一个好的、最小的、完整的代码示例,清楚地显示您尝试了什么,并包括一个精确、详细的解释,说明该代码的作用及与您想要的有何不同。点击此处了解更多信息。 - Peter Duniho
2个回答

3
您可以在Border上注册PreviewMouseDown事件。如果单击包含元素,它也会触发。
private void Border_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
  var clickedElement = e.OriginalSource;
}

1

还有一种方法(虽然我认为不够简洁),但如果您需要定制行为,它可能会很有用...也许 :)

我们创建自定义滚动视图,然后使用它来替换标准视图,我们的自定义控件只需将鼠标按下事件传播到其父级(此示例过于简化,因此在当前状态下不适合生产使用)。

public class CustomScrollViewer : ScrollViewer
{
    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        ((e.Source as FrameworkElement).Parent as UIElement).RaiseEvent(e);
    }
}

对于像我这样不熟悉 PreviewMouseDown 方法的人,以下是一些信息 - 它使用了名为隧道(从上到下)的路由策略,这与冒泡(从下到上)相反。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接