WPF 可缩放ScrollView(方式二)

方式一相比:

增加了缩放Maximun、Minimun和Value值,以及可供监听缩放变化的ValueChanged事件。

  1     public class ScaleScrollView : ScrollViewer
  2     {
  3         readonly List<object> ValueChangedEvents = new List<object>();
  4         public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<double>), typeof(ScaleScrollView));
  5         /// <summary>
  6         /// 通过监听此事件对内容进行缩放
  7         /// </summary>
  8         public event RoutedPropertyChangedEventHandler<double> ValueChanged
  9         {
 10             add => AddHandler(ValueChangedEvent, value);
 11             remove => RemoveHandler(ValueChangedEvent, value);
 12         }
 13 
 14         #region Properties
 15 
 16 
 17         public double Maximum
 18         {
 19             get { return (double)GetValue(MaximumProperty); }
 20             set { SetValue(MaximumProperty, value); }
 21         }
 22 
 23         public static readonly DependencyProperty MaximumProperty =
 24             DependencyProperty.Register("Maximum", typeof(double), typeof(ScaleScrollView), new PropertyMetadata(1200d));
 25 
 26 
 27 
 28         public double Minimum
 29         {
 30             get { return (double)GetValue(MinimumProperty); }
 31             set { SetValue(MinimumProperty, value); }
 32         }
 33 
 34         public static readonly DependencyProperty MinimumProperty =
 35             DependencyProperty.Register("Minimum", typeof(double), typeof(ScaleScrollView), new PropertyMetadata(1d));
 36 
 37 
 38 
 39         public double SmallChange
 40         {
 41             get { return (double)GetValue(SmallChangeProperty); }
 42             set { SetValue(SmallChangeProperty, value); }
 43         }
 44 
 45         // Using a DependencyProperty as the backing store for SmallChange.  This enables animation, styling, binding, etc...
 46         public static readonly DependencyProperty SmallChangeProperty =
 47             DependencyProperty.Register("SmallChange", typeof(double), typeof(ScaleScrollView), new PropertyMetadata(1d));
 48 
 49 
 50 
 51         public double Value
 52         {
 53             get { return (double)GetValue(ValueProperty); }
 54             set { SetValue(ValueProperty, value); }
 55         }
 56 
 57         public static readonly DependencyProperty ValueProperty =
 58             DependencyProperty.Register("Value", typeof(double), typeof(ScaleScrollView),
 59                 new FrameworkPropertyMetadata(100d, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange, propertyChangedCallback: onValueConagend));
 60 
 61         private static void onValueConagend(DependencyObject d, DependencyPropertyChangedEventArgs e)
 62         {
 63             ScaleScrollView view = d as ScaleScrollView;
 64             int ov = Convert.ToInt32(e.OldValue);
 65             int nv = Convert.ToInt32(e.NewValue);
 66             
 67             RoutedPropertyChangedEventArgs<double> args = new RoutedPropertyChangedEventArgs<double>(ov, nv);
 68             args.RoutedEvent = ValueChangedEvent;
 69             view.RaiseEvent(args);
 70 
 71             if (args.Handled) return;
 72             if (view.Content is FrameworkElement element)
 73             {
 74                 double w = element.ActualWidth + element.ActualWidth * (nv - ov) / 100;
 75                 element.Width = w < 1.0 ? 1.0 : w;
 76                 double h = element.ActualHeight + element.ActualHeight * (nv - ov) / 100;
 77                 element.Height = h < 1.0 ? 1.0 : h;
 78             }
 79 
 80         }
 81 
 82 
 83         #endregion
 84 
 85         protected override void OnMouseWheel(MouseWheelEventArgs e)
 86         {
 87             if (e.Handled) { return; }
 88 
 89             if (ScrollInfo != null)
 90             {
 91                 //Shift+滚动:上下滚动
 92                 //Ctrl+滚动:左右滚动
 93                 //滚动:放大缩小
 94                 if (Keyboard.IsKeyDown(Key.LeftShift))
 95                 {
 96                     if (e.Delta > 0)
 97                         ScrollInfo.MouseWheelUp();
 98                     else
 99                         ScrollInfo.MouseWheelDown();
100                 }
101                 else if (Keyboard.IsKeyDown(Key.LeftCtrl))
102                 {
103                     if (e.Delta > 0)
104                         ScrollInfo.LineLeft();
105                     else
106                         ScrollInfo.MouseWheelRight();
107                 }
108                 else
109                 {
110                     Value += e.Delta > 0 ? SmallChange : -SmallChange;
111                 }
112             }
113 
114             e.Handled = true;
115         }
116     }

示例:

 1 <DockPanel>
 2     <WrapPanel DockPanel.Dock="Bottom">
 3          <Slider Name="sliderScale" Minimum="1" Value="100" Maximum="1000" SmallChange="1" LargeChange="50" IsSnapToTickEnabled="True" Width="100"/>
 4              <TextBlock Text="{Binding ElementName=sliderScale, Path=Value}" VerticalAlignment="Center"/>
 5     </WrapPanel>
 6     <controls:ScaleScrollView HorizontalScrollBarVisibility="Visible" Value="{Binding ElementName=sliderScale, Path=Value, Mode=TwoWay}">
 7          <Viewbox Name="viewbox">
 8              <Border Width="2000" Height="2000" Background="Orange">
 9                   <Canvas>
10                       <Rectangle Fill="Red" Width="1000" Height="1000"/>
11                   </Canvas>
12              </Border>
13          </Viewbox>
14     </controls:ScaleScrollView>
15 </DockPanel>

 

posted @ 2022-03-22 15:47  HotSky  阅读(374)  评论(0编辑  收藏  举报