WPF解决当ScrollViewer中嵌套ItemsControl时,不能使用鼠标来滚动翻页
1. ScrollViewer:滚动条容器,当内容超过指定的长度和宽度后,就会出现滚动条,而且可以使用鼠标中键来滚动,
简单例子如下:
1 <Window x:Class="ConnectScrollViewScrollingDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="400" Width="600"> 5 <Grid> 6 <!--the normal control--> 7 <ScrollViewer> 8 <StackPanel> 9 <TextBlock Text="123"></TextBlock> 10 <TextBlock Text="123"></TextBlock> 11 <TextBlock Text="123"></TextBlock> 12 <Label Content="456"/> 13 <Label Content="456"/> 14 <Label Content="456"/> 15 <Label Content="456"/> 16 <UserControl Content="789"/> 17 <UserControl Content="789"/> 18 <UserControl Content="789"/> 19 <UserControl Content="789"/> 20 <UserControl Content="789"/> 21 <Button Content="010"/> 22 <Button Content="010"/> 23 <Button Content="010"/> 24 <Button Content="010"/> 25 <Button Content="010"/> 26 <Rectangle Height="20" Fill="Black"/> 27 <Rectangle Height="20" Fill="Black"/> 28 <Rectangle Height="20" Fill="Black"/> 29 <Rectangle Height="20" Fill="Black"/> 30 <Rectangle Height="20" Fill="Black"/> 31 <Rectangle Height="20" Fill="Black"/> 32 </StackPanel> 33 </ScrollViewer> 34 </Grid> 35 </Window>
当在ScrollViewer中的控件是普通控件时,使用的情况一切正常
2.当ScrollViewer中包含ItemsControl时,因为ItemsControl自身也有滚动的功能,所以在未做任何处理下的例子:
1 <Window x:Class="ConnectScrollViewScrollingDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="400" Width="600"> 5 <Grid> 6 7 <!--with ListBox--> 8 <ScrollViewer Grid.Column="1"> 9 <StackPanel> 10 <ListBox Background="AliceBlue"> 11 <ListBox.ItemsSource> 12 <x:Array Type="TextBox"> 13 <TextBox Text="00000"/> 14 <TextBox Text="00000"/> 15 <TextBox Text="00000"/> 16 <TextBox Text="00000"/> 17 <TextBox Text="00000"/> 18 <TextBox Text="00000"/> 19 <TextBox Text="00000"/> 20 <TextBox Text="00000"/> 21 <TextBox Text="00000"/> 22 <TextBox Text="00000"/> 23 <TextBox Text="00000"/> 24 <TextBox Text="00000"/> 25 <TextBox Text="00000"/> 26 <TextBox Text="00000"/> 27 <TextBox Text="00000"/> 28 <TextBox Text="00000"/> 29 <TextBox Text="00000"/> 30 <TextBox Text="00000"/> 31 <TextBox Text="00000"/> 32 <TextBox Text="00000"/> 33 <TextBox Text="00000"/> 34 </x:Array> 35 </ListBox.ItemsSource> 36 </ListBox> 37 <ListBox Height="50" Background="Green"> 38 <ListBox.ItemsSource> 39 <x:Array Type="Rectangle"> 40 <Rectangle Height="20" Fill="Red"/> 41 <Rectangle Height="20" Fill="Red"/> 42 <Rectangle Height="20" Fill="Orange"/> 43 <Rectangle Height="20" Fill="Red"/> 44 <Rectangle Height="20" Fill="Gray"/> 45 <Rectangle Height="20" Fill="Red"/> 46 <Rectangle Height="20" Fill="Red"/> 47 </x:Array> 48 </ListBox.ItemsSource> 49 </ListBox> 50 </StackPanel> 51 </ScrollViewer> 52 </Grid> 53 </Window>
细心一点,你就会发现,其实仅仅是在ListBox的元素区域中使用鼠标滚轮无效,但在两个ListBox的交界处还是有效果的,所以
我们需要做的,就是讲ListBox的滚动事件与外层的ScrollViewer的滚动关联起来,核心代码如下:
1 public void UseTheScrollViewerScrolling(FrameworkElement fElement) 2 { 3 fElement.PreviewMouseWheel += (sender, e) => 4 { 5 var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta); 6 eventArg.RoutedEvent = UIElement.MouseWheelEvent; 7 eventArg.Source = sender; 8 fElement.RaiseEvent(eventArg); 9 }; 10 }
代码中使用了FrameworkElement类型的参数,因为这个方法的作用是让内层的ListBox与外层的ScrollViewer关联起来,但当两者
之间还有别的元素时,这个方法的参数应该传入的是ScrollViewer的直接子元素,而不是深层的ListBox。
完整代码:MainWindow.xaml
1 <Window x:Class="ConnectScrollViewScrollingDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="400" Width="900"> 5 <Grid> 6 <Grid.ColumnDefinitions> 7 <ColumnDefinition></ColumnDefinition> 8 <ColumnDefinition></ColumnDefinition> 9 <ColumnDefinition></ColumnDefinition> 10 </Grid.ColumnDefinitions> 11 <!--the normal control--> 12 <ScrollViewer> 13 <StackPanel> 14 <TextBlock Text="123"></TextBlock> 15 <TextBlock Text="123"></TextBlock> 16 <TextBlock Text="123"></TextBlock> 17 <Label Content="456"/> 18 <Label Content="456"/> 19 <Label Content="456"/> 20 <Label Content="456"/> 21 <UserControl Content="789"/> 22 <UserControl Content="789"/> 23 <UserControl Content="789"/> 24 <UserControl Content="789"/> 25 <UserControl Content="789"/> 26 <Button Content="010"/> 27 <Button Content="010"/> 28 <Button Content="010"/> 29 <Button Content="010"/> 30 <Button Content="010"/> 31 <Rectangle Height="20" Fill="Black"/> 32 <Rectangle Height="20" Fill="Black"/> 33 <Rectangle Height="20" Fill="Black"/> 34 <Rectangle Height="20" Fill="Black"/> 35 <Rectangle Height="20" Fill="Black"/> 36 <Rectangle Height="20" Fill="Black"/> 37 </StackPanel> 38 </ScrollViewer> 39 40 <!--with ListBox--> 41 <ScrollViewer Grid.Column="1"> 42 <StackPanel> 43 <ListBox Background="AliceBlue"> 44 <ListBox.ItemsSource> 45 <x:Array Type="TextBox"> 46 <TextBox Text="00000"/> 47 <TextBox Text="00000"/> 48 <TextBox Text="00000"/> 49 <TextBox Text="00000"/> 50 <TextBox Text="00000"/> 51 <TextBox Text="00000"/> 52 <TextBox Text="00000"/> 53 <TextBox Text="00000"/> 54 <TextBox Text="00000"/> 55 <TextBox Text="00000"/> 56 <TextBox Text="00000"/> 57 <TextBox Text="00000"/> 58 <TextBox Text="00000"/> 59 <TextBox Text="00000"/> 60 <TextBox Text="00000"/> 61 <TextBox Text="00000"/> 62 <TextBox Text="00000"/> 63 <TextBox Text="00000"/> 64 <TextBox Text="00000"/> 65 <TextBox Text="00000"/> 66 <TextBox Text="00000"/> 67 </x:Array> 68 </ListBox.ItemsSource> 69 </ListBox> 70 <ListBox Height="50" Background="Green"> 71 <ListBox.ItemsSource> 72 <x:Array Type="Rectangle"> 73 <Rectangle Height="20" Fill="Red"/> 74 <Rectangle Height="20" Fill="Red"/> 75 <Rectangle Height="20" Fill="Orange"/> 76 <Rectangle Height="20" Fill="Red"/> 77 <Rectangle Height="20" Fill="Gray"/> 78 <Rectangle Height="20" Fill="Red"/> 79 <Rectangle Height="20" Fill="Red"/> 80 </x:Array> 81 </ListBox.ItemsSource> 82 </ListBox> 83 </StackPanel> 84 </ScrollViewer> 85 86 <!--with ListBox and Grid--> 87 <ScrollViewer Grid.Column="2"> 88 <Grid x:Name="grid"> 89 <StackPanel> 90 <ListBox Background="AliceBlue"> 91 <ListBox.ItemsSource> 92 <x:Array Type="TextBox"> 93 <TextBox Text="00000"/> 94 <TextBox Text="00000"/> 95 <TextBox Text="00000"/> 96 <TextBox Text="00000"/> 97 <TextBox Text="00000"/> 98 <TextBox Text="00000"/> 99 <TextBox Text="00000"/> 100 <TextBox Text="00000"/> 101 <TextBox Text="00000"/> 102 <TextBox Text="00000"/> 103 <TextBox Text="00000"/> 104 <TextBox Text="00000"/> 105 <TextBox Text="00000"/> 106 <TextBox Text="00000"/> 107 <TextBox Text="00000"/> 108 <TextBox Text="00000"/> 109 <TextBox Text="00000"/> 110 <TextBox Text="00000"/> 111 <TextBox Text="00000"/> 112 <TextBox Text="00000"/> 113 <TextBox Text="00000"/> 114 </x:Array> 115 </ListBox.ItemsSource> 116 </ListBox> 117 <ListBox Height="50" Background="Green"> 118 <ListBox.ItemsSource> 119 <x:Array Type="Rectangle"> 120 <Rectangle Height="20" Fill="Red"/> 121 <Rectangle Height="20" Fill="Red"/> 122 <Rectangle Height="20" Fill="Orange"/> 123 <Rectangle Height="20" Fill="Red"/> 124 <Rectangle Height="20" Fill="Gray"/> 125 <Rectangle Height="20" Fill="Red"/> 126 <Rectangle Height="20" Fill="Red"/> 127 </x:Array> 128 </ListBox.ItemsSource> 129 </ListBox> 130 </StackPanel> 131 </Grid> 132 133 </ScrollViewer> 134 </Grid> 135 </Window>
MainWindow.xaml.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 16 namespace ConnectScrollViewScrollingDemo 17 { 18 /// <summary> 19 /// Interaction logic for MainWindow.xaml 20 /// </summary> 21 public partial class MainWindow : Window 22 { 23 public MainWindow() 24 { 25 InitializeComponent(); 26 UseTheScrollViewerScrolling(grid); 27 } 28 29 public void UseTheScrollViewerScrolling(FrameworkElement fElement) 30 { 31 fElement.PreviewMouseWheel += (sender, e) => 32 { 33 var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta); 34 eventArg.RoutedEvent = UIElement.MouseWheelEvent; 35 eventArg.Source = sender; 36 fElement.RaiseEvent(eventArg); 37 }; 38 } 39 } 40 }