1 public class ScaleScrollView : ScrollViewer 2 { 3 List<object> MouseWheelEvents = new List<object>(); 4 /// <summary> 5 /// 通过监听此事件对内容进行缩放 6 /// </summary> 7 public event MouseWheelEventHandler MouseWheeled 8 { 9 add => MouseWheelEvents.Add(value); 10 remove => MouseWheelEvents.Remove(value); 11 } 12 13 public override void OnApplyTemplate() 14 { 15 base.OnApplyTemplate(); 16 } 17 18 protected override void OnMouseWheel(MouseWheelEventArgs e) 19 { 20 if (e.Handled) { return; } 21 22 if (ScrollInfo != null) 23 { 24 //Shift+滚动:上下滚动 25 //Ctrl+滚动:左右滚动 26 //滚动:放大缩小 27 if (Keyboard.IsKeyDown(Key.LeftShift)) 28 { 29 if (e.Delta > 0) 30 ScrollInfo.MouseWheelUp(); 31 else 32 ScrollInfo.MouseWheelDown(); 33 } 34 else if (Keyboard.IsKeyDown(Key.LeftCtrl)) 35 { 36 if (e.Delta > 0) 37 ScrollInfo.LineLeft(); 38 else 39 ScrollInfo.MouseWheelRight(); 40 } 41 else 42 { 43 foreach (var item in MouseWheelEvents) 44 { 45 (item as MouseWheelEventHandler)?.Invoke(this, e); 46 if (e.Handled) break; 47 } 48 } 49 } 50 51 e.Handled = true; 52 } 53 }
示例:
1 <local:ScaleScrollView HorizontalScrollBarVisibility="Visible" MouseWheeled="ScrollViewer_MouseWheel"> 2 <Viewbox Name="viewbox"> 3 <Border Width="2000" Height="2000" Background="Orange"> 4 <Canvas> 5 <Rectangle Fill="Red" Width="1000" Height="1000"/> 6 </Canvas> 7 </Border> 8 </Viewbox> 9 </local:ScaleScrollView>
1 private void ScrollViewer_MouseWheel(object sender, MouseWheelEventArgs e) 2 { 3 if (viewbox == null) return; 4 double w = viewbox.ActualWidth + viewbox.ActualWidth * (e.Delta > 0 ? 1 : -1) / 100; 5 if (w >= 0) 6 viewbox.Width = w; 7 double h = viewbox.ActualHeight + viewbox.ActualHeight * (e.Delta > 0 ? 1 : -1) / 100; 8 if (h >= 0) 9 viewbox.Height = h; 10 }
配合Slider使用:
<Slider Name="sliderScale" Minimum="1" Value="100" Maximum="1000" SmallChange="1" LargeChange="50" ValueChanged="sliderScale_ValueChanged" Width="100"/>
1 private void ScrollViewer_MouseWheel(object sender, MouseWheelEventArgs e) 2 { 3 sliderScale.Value += e.Delta > 0 ? 1 : -1; 4 } 5 6 private void sliderScale_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 7 { 8 if (viewbox == null) return; 9 double w = viewbox.ActualWidth + viewbox.ActualWidth * (e.NewValue > e.OldValue ? 1 : -1) / 100; 10 if (w >= 0) 11 viewbox.Width = w; 12 double h = viewbox.ActualHeight + viewbox.ActualHeight * (e.NewValue > e.OldValue ? 1 : -1) / 100; 13 if (h >= 0) 14 viewbox.Height = h; 15 }