WPF中透明窗口实现拖拽功能

前言

默认创建的窗口是可以拖拽放大缩小的,但是如果窗口设置为透明,就不能拖拽了。

窗口透明

添加这几个属性就行

1
2
3
4
AllowsTransparency="True"
Background="Transparent"
Topmost="True"
WindowStyle="None"

位置拖拽

1
2
3
4
5
6
<StackPanel
Grid.Row="1"
Background="#33000000"
Cursor="Hand"
MouseLeftButtonDown="WindowMouseLeftButtonDown"
Orientation="Horizontal" />

事件

1
2
3
4
5
6
7
private void WindowMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
DragMove();
}
}

大小拖拽

方式1

添加四个角 并设置事件

这种方式拖动左上、左下、右上都会导致窗口抖动,可以只保留右下。

页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<Grid Name="ImgGrid" Margin="0,0,0,0">
<Border
Margin="5"
Background="#333333"
BorderBrush="#2D8CF0"
BorderThickness="1">
<Image
Name="MImg"
MouseLeftButtonDown="Window_MouseLeftButtonDown_1"
Source="/Images/TouPing/phone_bg.jpg" />
</Border>

<Grid Name="MThumpGrid">
<Thumb
Width="16"
Height="16"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Cursor="ScrollNW"
DragDelta="LeftTop_DragDelta" />

<Thumb
Width="16"
Height="16"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Cursor="ScrollNE"
DragDelta="RightTop_DragDelta" />

<Thumb
Width="16"
Height="16"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Cursor="ScrollSW"
DragDelta="LeftBottom_DragDelta" />

<Thumb
Width="16"
Height="16"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Cursor="ScrollSE"
DragDelta="RightBottom_DragDelta" />
</Grid>
</Grid>

样式调整

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Window.Resources>
<Style TargetType="Thumb">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Ellipse
Fill="White"
Stroke="#2D8CF0"
StrokeThickness="2" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>

事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
private void LeftTop_DragDelta(object sender, DragDeltaEventArgs e)
{
if (Width <= 400 && e.HorizontalChange > 0)
{
return;
}
if (Height <= 400 && e.VerticalChange > 0)
{
return;
}
Left += e.HorizontalChange;
Top += e.VerticalChange;
Width -= e.HorizontalChange;
Height -= e.VerticalChange;
}

private void LeftBottom_DragDelta(object sender, DragDeltaEventArgs e)
{
if (Width <= 400 && e.HorizontalChange > 0)
{
return;
}
if (Height <= 400 && e.VerticalChange < 0)
{
return;
}
Left += e.HorizontalChange;
Width -= e.HorizontalChange;
Height += e.VerticalChange;
}

private void RightTop_DragDelta(object sender, DragDeltaEventArgs e)
{
if (Width <= 400 && e.HorizontalChange < 0)
{
return;
}
if (Height <= 400 && e.VerticalChange > 0)
{
return;
}
Top += e.VerticalChange;
Width += e.HorizontalChange;
Height -= e.VerticalChange;
}

private void RightBottom_DragDelta(object sender, DragDeltaEventArgs e)
{
if (Width <= 400 && e.HorizontalChange < 0)
{
return;
}
if (Height <= 400 && e.VerticalChange < 0)
{
return;
}
Width += e.HorizontalChange;
Height += e.VerticalChange;
}

方式2

只需要窗口设置WindowChrome即可

1
2
3
4
<!--  WindowChrome  -->
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" ResizeBorderThickness="20" />
</WindowChrome.WindowChrome>

窗口等比例缩放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#region [等比例调整窗口尺寸(Proportional Resize window)]

//最后的宽度(Last Width)
private int LastWidth;

//最后的高度(Last Height)
private int LastHeight;

//这个属性是指 窗口的宽度和高度的比例(宽度/高度)(4:3)
private float AspectRatio = 4.0f / 3.0f;

/// <summary>
/// 捕获窗口拖拉消息
/// </summary>
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = HwndSource.FromVisual(this) as HwndSource;
if (source != null)
{
source.AddHook(new HwndSourceHook(WinProc));
}
}

public const Int32 WM_EXITSIZEMOVE = 0x0232;

/// <summary>
/// 重载窗口消息处理函数
/// </summary>
private IntPtr WinProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, ref Boolean handled)
{
IntPtr result = IntPtr.Zero;
switch (msg)
{
//处理窗口消息 (Handle window messages)
case WM_EXITSIZEMOVE:
{
//上下拖拉窗口 (Drag window vertically)
if (this.Height != LastHeight)
{
this.Width = this.Height * AspectRatio;
}
// 左右拖拉窗口 (Drag window horizontally)
else if (this.Width != LastWidth)
{
this.Height = this.Width / AspectRatio;
}

LastWidth = (int)this.Width;
LastHeight = (int)this.Height;
break;
}
}
return result;
}
#endregion