WPF无边框透明窗体的缩放

WPF中的无边框透明窗体,由于没有边并且透明,窗体无法进行缩放操作,今天来讲解如何解决这个问题。

先说一下思路,我们先手为该窗体添加4个边,4个角用于缩放操作,然后再为他们写事件,完成拖放操作。

xaml代码:

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
< Window x:Class = "WpfResizeWindow.Window1"
    Title = "Window1" Height = "300" Width = "300" WindowStyle = "None" AllowsTransparency = "True" >
    < Grid >
        < Grid.RowDefinitions >
            < RowDefinition Height = "4" />
            < RowDefinition />
            < RowDefinition Height = "4" />
        </ Grid.RowDefinitions >
        < Grid.ColumnDefinitions >
            < ColumnDefinition Width = "4" />
            < ColumnDefinition />
            < ColumnDefinition Width = "4" />
        </ Grid.ColumnDefinitions >
        < Rectangle Name = "ResizeTopLeft" Fill = "Black" Grid.Row = "0" Grid.Column = "0" MouseMove = "ResizePressed" MouseDown = "ResizePressed" />
        < Rectangle Name = "ResizeTop" Fill = "Black" Grid.Row = "0" Grid.Column = "1" MouseMove = "ResizePressed" MouseDown = "ResizePressed" />
        < Rectangle Name = "ResizeTopRight" Fill = "Black" Grid.Row = "0" Grid.Column = "2" MouseMove = "ResizePressed" MouseDown = "ResizePressed" />
        < Rectangle Name = "ResizeLeft" Fill = "Black" Grid.Row = "1" Grid.Column = "0" MouseMove = "ResizePressed" MouseDown = "ResizePressed" />
        < Rectangle Name = "ResizeRight" Fill = "Black" Grid.Row = "1" Grid.Column = "3" MouseMove = "ResizePressed" MouseDown = "ResizePressed" />
        < Rectangle Name = "ResizeBottomLeft" Fill = "Black" Grid.Row = "3" Grid.Column = "0" MouseMove = "ResizePressed" MouseDown = "ResizePressed" />
        < Rectangle Name = "ResizeBottom" Fill = "Black" Grid.Row = "3" Grid.Column = "1" MouseMove = "ResizePressed" MouseDown = "ResizePressed" />
        < Rectangle Name = "ResizeBottomRight" Fill = "Black" Grid.Row = "3" Grid.Column = "2" MouseMove = "ResizePressed" MouseDown = "ResizePressed" />
    </ Grid >
</ Window >

cs代码:

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
60
61
62
63
64
65
66
67
68
69
public partial class Window1 : Window
{
    private const int WM_SYSCOMMAND = 0x112;
    private HwndSource _HwndSource;
    private Dictionary<ResizeDirection, Cursor> cursors = new Dictionary<ResizeDirection, Cursor>
    {
        {ResizeDirection.Top, Cursors.SizeNS},
        {ResizeDirection.Bottom, Cursors.SizeNS},
        {ResizeDirection.Left, Cursors.SizeWE},
        {ResizeDirection.Right, Cursors.SizeWE},
        {ResizeDirection.TopLeft, Cursors.SizeNWSE},
        {ResizeDirection.BottomRight, Cursors.SizeNWSE},
        {ResizeDirection.TopRight, Cursors.SizeNESW},
        {ResizeDirection.BottomLeft, Cursors.SizeNESW}
    };
    private enum ResizeDirection
    {
        Left = 1,
        Right = 2,
        Top = 3,
        TopLeft = 4,
        TopRight = 5,
        Bottom = 6,
        BottomLeft = 7,
        BottomRight = 8,
    }
    [DllImport( "user32.dll" , CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    public Window1()
    {
        InitializeComponent();
        this .SourceInitialized += delegate ( object sender, EventArgs e)
        {
            this ._HwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
        };
        this .MouseMove += new MouseEventHandler(Window_MouseMove);
    }
    void Window_MouseMove( object sender, MouseEventArgs e)
    {
        if (Mouse.LeftButton != MouseButtonState.Pressed)
        {
            FrameworkElement element = e.OriginalSource as FrameworkElement;
            if (element != null && !element.Name.Contains( "Resize" ))
                this .Cursor = Cursors.Arrow;
        }
    }
    private void ResizePressed( object sender, MouseEventArgs e)
    {
        FrameworkElement element = sender as FrameworkElement;
        ResizeDirection direction = (ResizeDirection)Enum.Parse( typeof (ResizeDirection), element.Name.Replace( "Resize" , "" ));
        this .Cursor = cursors[direction];
        if (e.LeftButton == MouseButtonState.Pressed)
            ResizeWindow(direction);
    }
    private void ResizeWindow(ResizeDirection direction)
    {
        SendMessage(_HwndSource.Handle, WM_SYSCOMMAND, (IntPtr)(61440 + direction), IntPtr.Zero);
    }
}

从代码可以看出,先注册4个边和4个角的MouseMove和MouseDown事件,鼠标移动到拖放内容上时,判断鼠标悬停在那个边上,改变鼠标指针变成相应对象,判断鼠标是否按下,如果按下了,则发送Win32消息,进行拖放操作,从代码中可以看出来最终的拖放还是使用Win32 api来实现,因为,如果完全用wpf的事件进行拖放的话,实在是太慢了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值