效果图如下:
Code: /Files/lovebread/CustomWindow.rar
实现思路:
1.继承Window类
2.为自定义的CustomWindow类设计窗体样式(使用Blend很方便!)
3.为窗体增加最大最小化和关闭按钮,并实现鼠标拖拽改变窗体大小(使用Derek Bartram的WindowResizer.dll库)
代码说明:
1.继承Window类
创建CustomWindow类,继承自System.Window
代码 public class CustomWindow : Window{ public CustomWindow() { // 加载样式 InitializeStyle(); // 加载事件委托 this .Loaded += delegate { InitializeEvent(); }; // 解决最大化覆盖任务栏问题 this .SourceInitialized += new EventHandler(win_SourceInitialized); }}代码 < src:CustomWindow x:Class ="windowStyle1.Window1" xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:src ="clr-namespace:windowStyle1" Title ="CustomWindow" Height ="358" Width ="649" AllowsTransparency ="True" WindowStyle ="None" >
2.为自定义的CustomWindow类设计窗体样式
窗体样式的设计可以使用Expression Blend来进行可视化开发,非常方便
Blend会自动生成样式的xmal文件:
代码 < ResourceDictionary xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d ="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable ="d" xmlns:Microsoft_Windows_Themes ="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna" > < ControlTemplate x:Key ="WindowTemplateKey" TargetType ="{x:Type Window}" > < Border Background ="{TemplateBinding Background}" BorderBrush ="{TemplateBinding BorderBrush}" BorderThickness ="{TemplateBinding BorderThickness}" > < Grid > < AdornerDecorator > < ContentPresenter /> </ AdornerDecorator > < ResizeGrip x:Name ="WindowResizeGrip" HorizontalAlignment ="Right" VerticalAlignment ="Bottom" IsTabStop ="false" Visibility ="Collapsed" /> </ Grid > </ Border > < ControlTemplate.Triggers > < MultiTrigger > < MultiTrigger.Conditions > < Condition Property ="ResizeMode" Value ="CanResizeWithGrip" /> < Condition Property ="WindowState" Value ="Normal" /> </ MultiTrigger.Conditions > < Setter Property ="Visibility" TargetName ="WindowResizeGrip" Value ="Visible" /> </ MultiTrigger > </ ControlTemplate.Triggers > </ ControlTemplate >
3.为窗体增加最大最小化和关闭按钮,并实现鼠标拖拽改变窗体大小
按钮事件比较简单,通过分别为三个按钮添加Click事件即可
代码 /// <summary> /// 加载按钮事件委托 /// </summary> private void InitializeEvent(){ ControlTemplate baseWindowTemplate = (ControlTemplate)App.Current.Resources[ " CustomWindowControlTemplate " ]; Button minBtn = (Button)baseWindowTemplate.FindName( " btnMin " , this ); minBtn.Click += delegate { this .WindowState = WindowState.Minimized; }; Button maxBtn = (Button)baseWindowTemplate.FindName( " btnMax " , this ); maxBtn.Click += delegate { this .WindowState = ( this .WindowState == WindowState.Normal ? WindowState.Maximized : WindowState.Normal); }; Button closeBtn = (Button)baseWindowTemplate.FindName( " btnClose " , this ); closeBtn.Click += delegate { this .Close(); }; Border tp = (Border)baseWindowTemplate.FindName( " topborder " , this ); tp.MouseLeftButtonDown += delegate { this .DragMove(); };}仅仅这样实现的话还不够,因为窗体最大化后会覆盖任务栏,这是我们不希望看到的,所以还必须通过WINDOW API的窗口句柄来定义最大化后的尺寸
代码 /// <summary> /// 重绘窗体大小 /// </summary> void win_SourceInitialized( object sender, EventArgs e){ System.IntPtr handle = ( new WinInterop.WindowInteropHelper( this )).Handle; WinInterop.HwndSource.FromHwnd(handle).AddHook( new WinInterop.HwndSourceHook(WindowProc));}...[DllImport( " user32 " )] internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);[DllImport( " User32 " )] internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);... private static System.IntPtr WindowProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled){ switch (msg) { case 0x0024 : WmGetMinMaxInfo(hwnd, lParam); handled = true ; break ; } return (System.IntPtr) 0 ;}具体代码请看附件
这部分参考:http://blogs.msdn.com/llobo/archive/2006/08/01/Maximizing-window-_2800_with-WindowStyle_3D00_None_2900_-considering-Taskbar.aspx
最后是实现用鼠标拖拽改变窗体大小
这部分可以参考Derek Bartram的文章http://www.codeproject.com/KB/WPF/WPF_Window_Resizing.aspx
首先将封装好的WindowResizer.dll文件拷到工程目录下,并在工程中添加对它的引用
然后在Windows1这个CustomWindow类的实例中绘制左右及底部5个拖拽热区(矩形)
最后在Window1.xaml.cs中添加事件委托即可
代码 /// <summary> /// 加载Resize委托 /// </summary> public void InitializeResizeHandle(){ WindowResizer wr = new WindowResizer( this ); wr.addResizerRight(right); wr.addResizerLeft(left); wr.addResizerDown(bottom); wr.addResizerLeftDown(leftbottom); wr.addResizerRightDown(rightbottom); // wr.addResizerUp(topSizeGrip); // wr.addResizerLeftUp(topLeftSizeGrip); // wr.addResizerRightUp(topRightSizeGrip); }
大功告成了!