1. 程式人生 > >WPF中的無邊框透明可縮放窗體

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的事件進行拖放的話,實在是太慢了。