子列表框的滚动触发父滚动查看器 'Scroll Changed' 事件
Parent Scroll-viewer 'Scroll Changed' event firing by Child List-box's Scroll
我在滚动查看器中有一个列表框。 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 => 发生了一些事情!
我试过启用或禁用 HorizontalScrollBar,但同样的事情发生了...
我的 VerticalScrollBar 现在被禁用了,我做到了 'Hidden',但现在它也隐藏了 ListBox 的垂直滚动条,我也无法通过鼠标滚轮滚动 ListBox
提前致谢...
发生这种情况是因为 ScrollViewer.ScrollChanged
is a routed 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))
{
}
}
我在滚动查看器中有一个列表框。 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 => 发生了一些事情!
我试过启用或禁用 HorizontalScrollBar,但同样的事情发生了... 我的 VerticalScrollBar 现在被禁用了,我做到了 'Hidden',但现在它也隐藏了 ListBox 的垂直滚动条,我也无法通过鼠标滚轮滚动 ListBox
提前致谢...
发生这种情况是因为 ScrollViewer.ScrollChanged
is a routed 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))
{
}
}