事件冒泡问题(ScrollViewer)

5

我在事件冒泡方面遇到了问题。我成功地在边框、网格和堆栈面板中实现了事件冒泡,但在ScrollViewer中却没有。

如果您查看下面的示例,您会注意到当您单击TextBlock时,事件会冒泡到Grid。但是当我包含ScrollViewer时,事件停留在此处,不会发送到Grid。

有人知道这是为什么,并且是否可以解决吗?我真的需要能够通过ScrollViewer进行事件冒泡,因为我经常使用它。

<Grid MouseLeftButtonDown="Grid_MouseLeftButtonDown">
        <!--<ScrollViewer MouseLeftButtonDown="ScrollViewer_MouseLeftButtonDown">-->
            <StackPanel Orientation="Vertical" MouseLeftButtonDown="StackPanel_MouseLeftButtonDown">
                <TextBlock Text="Click me to bubble an event" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
            </StackPanel>
        <!--</ScrollViewer>-->
</Grid>


public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("LayoutRoot clicked");
    }


    private void ScrollViewer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("ScrollViewer clicked");
        e.Handled = false;
    }

    private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("StackPanel clicked");
        e.Handled = false;
    }

    private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("Textblock clicked");
        e.Handled = false;
    }
}

ScrollViewer是一个密封类,不能被继承,使用AddHandler。 - Adam
3个回答

1
使用AddHandler(yourDelegate, True)语法添加事件处理程序,这将忽略可视树中其他控件设置的Handled标志。

0

我遇到了这个问题,用户572559发布的修复方法解决了我的问题。对于那些需要的人,以下是我所做的(修改后发布):

_scrollViewer = new ScrollViewer();
_scrollViewer.AddHandler(
    ScrollViewer.MouseLeftButtonDownEvent, 
    new MouseButtonEventHandler(OnMouseLeftButtonDown),
    true);
_scrollViewer.AddHandler(
    ScrollViewer.MouseLeftButtonUpEvent, 
    new MouseButtonEventHandler(OnMouseLeftButtonUp), 
    true);

...

    void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        ...
    }

    void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        ...
    }

请注意,如果您正在处理这些内容,您可能也需要处理MouseMove事件。MouseMove对我来说可以正常工作,而且似乎也不支持这种方式(不是冒泡事件)。

0

您可以通过像这样覆盖ScrollViewer来防止在MouseButtonEventArgs上出现e.Handled

public sealed class ClickScrollViewer : ScrollViewer
{
    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        this.Focus();
    }
}

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