WPF解决ScrollViewer内部鼠标滚轮无法控制上下翻页

文章讲述了在WPF中遇到ScrollViewer的鼠标滚轮无法在内部内容中正常滚动的问题,原因是内部的ItemsControl或ListBox有自己的滚动机制。为了解决这个问题,作者提供了将ListBox的滚动事件与外层ScrollViewer的滚动事件关联起来的方法,通过监听PreviewMouseWheel事件并重新触发MouseWheelEvent,实现了在ScrollViewer内任意位置使用鼠标滚轮进行滚动的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WPF解决ScrollViewer内部鼠标滚轮无法控制上下翻页

最近发现ScrollViewer使用时鼠标在内部内容中滚动不能使其上下翻,只有鼠标移到最右侧滚动条上才有用

于是查找到了这位大佬的解决方式,测试了一下解决了问题,记录一下原文地址

ScrollViewer:当内容超过指定长度和宽度后,会出现滚动条,且可以使用鼠标滚轮滚动控制

当ScrollViewer中包含ItemsControl时,因为ItemsControl自身也有滚动功能,所以未作任何处理时无法实现滚动控制

使用ListBox示例,下列代码无法实现滚动

<ScrollViewer Grid.Column="1">
                <StackPanel>
                    <ListBox Background="AliceBlue">
                        <ListBox.ItemsSource>
                            <x:Array Type="TextBox">
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                                <TextBox Text="00000"/>
                            </x:Array>
                        </ListBox.ItemsSource>
                    </ListBox>
                    <ListBox Height="50" Background="Green">
                        <ListBox.ItemsSource>
                            <x:Array Type="Rectangle">
                                <Rectangle Height="20" Fill="Red"/>
                                <Rectangle Height="20" Fill="Red"/>
                                <Rectangle Height="20" Fill="Orange"/>
                                <Rectangle Height="20" Fill="Red"/>
                                <Rectangle Height="20" Fill="Gray"/>
                                <Rectangle Height="20" Fill="Red"/>
                            </x:Array>
                        </ListBox.ItemsSource>
                    </ListBox>
                </StackPanel>
            </ScrollViewer>

解决方法:将ListBox的滚动事件与外层的ScrollViewer的滚动关联起来

public void UseTheScrollViewerScrolling(FrameworkElement fElement)
        {
            fElement.PreviewMouseWheel += (sender, e) =>
            {
                var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
                eventArg.RoutedEvent = UIElement.MouseWheelEvent;
                eventArg.Source = sender;
                fElement.RaiseEvent(eventArg);
            };
        }

当两者之间还有别的元素时,这个方法的参数应该传入的是ScrollViewer的直接子元素,而不是深层的ListBox
可实现滚动的代码如下:
xaml:

  <ScrollViewer Grid.Column="2">
                <Grid x:Name="grid">
                    <StackPanel >
                        <ListBox Background="AliceBlue">
                            <ListBox.ItemsSource>
                                <x:Array Type="TextBox">
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                    <TextBox Text="00000"/>
                                </x:Array>
                            </ListBox.ItemsSource>
                        </ListBox>
                        <ListBox Height="50" Background="Green">
                            <ListBox.ItemsSource>
                                <x:Array Type="Rectangle">
                                    <Rectangle Height="20" Fill="red"/>
                                    <Rectangle Height="20" Fill="red"/>
                                    <Rectangle Height="20" Fill="Orange"/>
                                    <Rectangle Height="20" Fill="red"/>
                                    <Rectangle Height="20" Fill="Gray"/>
                                    <Rectangle Height="20" Fill="red"/>
                                    <Rectangle Height="20" Fill="red"/>
                                </x:Array>
                            </ListBox.ItemsSource>
                        </ListBox>
                    </StackPanel>
                </Grid>
            </ScrollViewer>

C#:

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            UseTheScrollViewerScrolling(grid);
        }
        public void UseTheScrollViewerScrolling(FrameworkElement fElement)
        {
            fElement.PreviewMouseWheel += (sender, e) =>
            {
                var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
                eventArg.RoutedEvent = UIElement.MouseWheelEvent;
                eventArg.Source = sender;
                fElement.RaiseEvent(eventArg);
            };
        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值