WPF 窗体中的 Canvas 限定范围拖动 鼠标滚轴改变大小
xaml代码:
1 <Canvas Name="movBg">
2 <Canvas.Background>
3 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
4 <GradientStop Color="White" Offset="0" />
5 <GradientStop Color="#FFF5FF00" Offset="1" />
6 </LinearGradientBrush>
7 </Canvas.Background>
8 <Canvas Canvas.Top="50" Canvas.Left="50" Height="100" HorizontalAlignment="Left" Name="mov" VerticalAlignment="Top" Width="200" MouseLeftButtonDown="mov_MouseLeftButtonDown" MouseLeftButtonUp="mov_MouseLeftButtonUp" MouseMove="mov_MouseMove" MouseWheel="mov_MouseWheel" MaxWidth="300" MaxHeight="300">
9 <Border BorderThickness="1" BorderBrush="Black" Width="{Binding ElementName=mov,Path=Width}" Height="{Binding ElementName=mov,Path=Height}" MaxWidth="{Binding ElementName=mov,Path=MaxWidth}" MaxHeight="{Binding ElementName=mov,Path=MaxHeight}"></Border>
10 <Canvas.Background>
11 <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
12 <GradientStop Color="White" Offset="0" />
13 <GradientStop Color="#FFD679F2" Offset="1" />
14 </LinearGradientBrush>
15 </Canvas.Background>
16 </Canvas>
17 </Canvas>
C#代码:
1 #region 拖动选区,滚轴改变大小
2 //鼠标相对于被拖动的Canvas控件mov的坐标
3 Point childPoint = new Point();
4 //鼠标相对于作为容器的Canvas控件movBg的坐标
5 Point prevPoint = new Point();
6
7 private void mov_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
8 {
9 childPoint = e.GetPosition(mov);
10 }
11
12 private void mov_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
13 {
14 Canvas c = sender as Canvas;
15 Rect rc = new Rect(1, 1, movBg.ActualWidth, movBg.ActualHeight);
16 Rect childRc = new Rect(Canvas.GetLeft(c), Canvas.GetTop(c), c.ActualWidth, c.ActualHeight);
17 if (!rc.Contains(childRc))
18 {
19 childRc = AutoResize(rc, childRc);
20 c.SetValue(Canvas.LeftProperty, childRc.Left);
21 c.SetValue(Canvas.TopProperty, childRc.Top);
22 c.Width = childRc.Width;
23 c.Height = childRc.Height;
24 }
25 c.ReleaseMouseCapture();
26 }
27
28 private void mov_MouseMove(object sender, MouseEventArgs e)
29 {
30 if (e.LeftButton == MouseButtonState.Pressed)
31 {
32 Canvas c = sender as Canvas;
33
34 prevPoint = e.GetPosition(movBg);
35 double x = prevPoint.X - childPoint.X;
36 double y = prevPoint.Y - childPoint.Y;
37
38 Rect rc = new Rect(1, 1, movBg.ActualWidth, movBg.ActualHeight);
39 Rect childRc = new Rect(Canvas.GetLeft(c), Canvas.GetTop(c), c.ActualWidth, c.ActualHeight);
40 if (!rc.Contains(childRc))
41 {
42 childRc = AutoResize(rc, childRc);
43 c.SetValue(Canvas.LeftProperty, childRc.Left);
44 c.SetValue(Canvas.TopProperty, childRc.Top);
45 c.Width = childRc.Width;
46 c.Height = childRc.Height;
47 c.ReleaseMouseCapture();
48 }
49 else
50 {
51 c.SetValue(Canvas.LeftProperty, prevPoint.X - childPoint.X);
52 c.SetValue(Canvas.TopProperty, prevPoint.Y - childPoint.Y);
53 c.CaptureMouse();
54 }
55 }
56 }
57
58 private Rect AutoResize(Rect outerRc, Rect innerRc)
59 {
60 double with = innerRc.Width;
61 double height = innerRc.Height;
62
63 if (innerRc.Left < outerRc.Left)
64 {
65 innerRc.X = outerRc.Left + 1;
66 innerRc.Width = with;
67 }
68 if (innerRc.Right > outerRc.Right)
69 {
70 innerRc.X = outerRc.Right - with - 1;
71 innerRc.Width = with;
72 }
73 if (innerRc.Top < outerRc.Top)
74 {
75 innerRc.Y = outerRc.Top + 1;
76 innerRc.Height = height;
77 }
78 if (innerRc.Bottom > outerRc.Bottom)
79 {
80 innerRc.Y = outerRc.Bottom - height - 1;
81 innerRc.Height = height;
82 }
83 return innerRc;
84 }
85
86 private void mov_MouseWheel(object sender, MouseWheelEventArgs e)
87 {
88 double val = e.Delta * 0.001;
89 double wl = mov.Width * (val / 0.12) * 0.02;
90 double hl = mov.Height * (val / 0.12) * 0.02;
91
92 if ((Canvas.GetLeft(mov) - wl/2.0) > 0 && (Canvas.GetLeft(mov) + wl + mov.Width) <= movBg.ActualWidth &&
93 (Canvas.GetTop(mov) - hl/2.0) > 0 && (Canvas.GetTop(mov) + hl + mov.Height) <= movBg.ActualHeight &&
94 (mov.Width + wl) < mov.MaxWidth && (mov.Height + hl) < mov.MaxHeight)
95 {
96 mov.SetValue(Canvas.LeftProperty, Canvas.GetLeft(mov) - wl / 2.0);
97 mov.SetValue(Canvas.TopProperty, Canvas.GetTop(mov) - hl / 2.0);
98 mov.Width += wl;
99 mov.Height += hl;
100
101 }
102