【问题标题】:Parent Scroll-viewer 'Scroll Changed' event firing by Child List-box's Scroll子列表框的滚动触发父滚动查看器“滚动更改”事件
【发布时间】:2020-05-18 12:23:42
【问题描述】:

我在 Scroll Viewer 中有一个 ListBox。 Scroll Viewer 已附加一个 Scroll-Changed 侦听器,我在其中放置了一个:

MessageBox.Show("Something Happened!");

这是我的 WPF 代码:

        <ScrollViewer ScrollChanged="ScrollViewer_ScrollChanged" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled">
                <ListBox>
                    <ListBox.Items>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                        <ListBoxItem Content="item 2"/>
                    </ListBox.Items>
                </ListBox>
        </ScrollViewer>

现在的问题是,当我滚动 ListBox 时,不知何故 ScrollViewer 的 'ScrollChanged' 事件通过向我显示 MessageBox => 发生了一些事情来触发!

我尝试过启用或禁用 Horizo​​ntalScrollBar,但同样的事情发生了...... 我的 VerticalScrollBar 现在已禁用,我将其设置为“隐藏”,但现在它也隐藏了 ListBox 的垂直滚动条,我也无法通过鼠标滚轮滚动 ListBox

提前谢谢... ????

【问题讨论】:

  • 你好,我不明白是什么问题,你监听了一个滚动事件,你不希望代码在这个事件上触发?
  • 我不希望代码触发 ListBox 的 Scroll-Changed 事件。事件被分配给外层的Scroll Viewer,所以,它应该只在我们滚动Parent-ScrollViewer时触发代码,而不是当我们滚动内层ListBox时触发代码

标签: c# wpf events scrollview parent-child


【解决方案1】:

这是因为ScrollViewer.ScrollChangedrouted event。具体来说,它是一个冒泡事件,这意味着当它被引发时,它会沿着可视化树(从引发它的更深的元素,向上到根)寻找处理程序。

这可以让你做这样的事情:

<ListBox ScrollViewer.ScrollChanged="listBox_ScrollChanged"/>

因为ListBox 在内部使用ScrollViewer,您可以在ListBox 级别侦听ScrollChanged 事件并处理它,即使ListBox 本身并没有为此公开事件。

当然,这也会导致您遇到的情况。幸运的是,它很容易解决。在您的事件处理程序中,您可以使用 RoutedEventArgs.Source 来判断正在滚动的元素:

//Assuming the ScrollViewer you want to listen to is given the name "OutsideScrollViewer"

private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
    if (object.ReferenceEquals(e.Source,  OutsideScrollViewer))
    {

    }
}

【讨论】:

  • 我们可以使用 (sender as ScrollViewer) == OutsideScrollViewer 吗?
  • 反之亦然...我在 OutsideScrollViewer 的滚动更改事件中检查了参考...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 2022-01-28
  • 1970-01-01
相关资源
最近更新 更多