WPF中的无边框透明可缩放窗体

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

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

xaml代码:

<Windowx:Class="WpfResizeWindow.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"Height="300"Width="300"WindowStyle="None"AllowsTransparency="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="4"/>
<RowDefinition/>
<RowDefinition Height="4"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinitionWidth="4"/>
<ColumnDefinition/>
<ColumnDefinitionWidth="4"/>
</Grid.ColumnDefinitions>
<RectangleName="ResizeTopLeft"Fill="Black"Grid.Row="0"Grid.Column="0"MouseMove="ResizePressed"MouseDown="ResizePressed"/>
<RectangleName="ResizeTop"Fill="Black"Grid.Row="0"Grid.Column="1"MouseMove="ResizePressed"MouseDown="ResizePressed"/>
<RectangleName="ResizeTopRight"Fill="Black"Grid.Row="0"Grid.Column="2"MouseMove="ResizePressed"MouseDown="ResizePressed"/>
<RectangleName="ResizeLeft"Fill="Black"Grid.Row="1"Grid.Column="0"MouseMove="ResizePressed"MouseDown="ResizePressed"/>
<RectangleName="ResizeRight"Fill="Black"Grid.Row="1"Grid.Column="3"MouseMove="ResizePressed"MouseDown="ResizePressed"/>
<RectangleName="ResizeBottomLeft"Fill="Black"Grid.Row="3"Grid.Column="0"MouseMove="ResizePressed"MouseDown="ResizePressed"/>
<RectangleName="ResizeBottom"Fill="Black"Grid.Row="3"Grid.Column="1"MouseMove="ResizePressed"MouseDown="ResizePressed"/>
<RectangleName="ResizeBottomRight"Fill="Black"Grid.Row="3"Grid.Column="2"MouseMove="ResizePressed"MouseDown="ResizePressed"/>
</Grid>
</Window>

cs代码:

public partial class Window1 : Window
{
privateconst intWM_SYSCOMMAND = 0x112;
privateHwndSource _HwndSource;

privateDictionary<ResizeDirection, Cursor> cursors = newDictionary<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}
};

privateenum ResizeDirection
{
Left = 1,
Right = 2,
Top = 3,
TopLeft = 4,
TopRight = 5,
Bottom = 6,
BottomLeft = 7,
BottomRight = 8,
}

[DllImport("user32.dll", CharSet = CharSet.Auto)]
privatestatic externIntPtr SendMessage(IntPtr hWnd, uintMsg, IntPtr wParam, IntPtr lParam);

publicWindow1()
{
InitializeComponent();

this.SourceInitialized +=delegate(objectsender, EventArgs e)
{
this._HwndSource = PresentationSource.FromVisual((Visual)sender)as HwndSource;
};
this.MouseMove += new MouseEventHandler(Window_MouseMove);
}

voidWindow_MouseMove(objectsender, MouseEventArgs e)
{
if (Mouse.LeftButton != MouseButtonState.Pressed)
{
FrameworkElement element = e.OriginalSource asFrameworkElement;
if (element != null && !element.Name.Contains("Resize"))
this.Cursor = Cursors.Arrow;
}
}

privatevoid ResizePressed(objectsender, MouseEventArgs e)
{
FrameworkElement element = sender asFrameworkElement;
ResizeDirection direction = (ResizeDirection)Enum.Parse(typeof(ResizeDirection), element.Name.Replace("Resize",""));

this.Cursor = cursors[direction];

if (e.LeftButton == MouseButtonState.Pressed)
ResizeWindow(direction);
}

privatevoid ResizeWindow(ResizeDirection direction)
{
SendMessage(_HwndSource.Handle, WM_SYSCOMMAND, (IntPtr)(61440 + direction), IntPtr.Zero);
}
}

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值