实现的WPF外边框窗体

最近看了一下wpf 越发喜欢. 边看边学,顺便做点东西. WPF 的窗体有点丑.就自己做个窗体,当学习的demo吧

效果图: 

实现功能: 最大化;最小化;关闭;按钮三态; 标题栏拖动;双击标题栏最大化或者还原;鼠标在窗体边缘拖动可调整窗体大小;

1. 右上角三个按钮采用样式实现效果

 1    <Style x:Key="ButtonIconStyle" TargetType="Button">
 2             <Setter Property="FontFamily" Value="/WindowResize;component/Resources/#iconfont"></Setter>
 3             <Setter Property="Background" Value="Transparent"></Setter>
 4             <Setter Property="Foreground" Value="Black"></Setter>
 5             <Setter Property="BorderBrush" Value="Transparent"></Setter>
 6             <Setter Property="Padding" Value="3,3,3,3" />
 7             <Setter Property="Template" >
 8                 <Setter.Value>
 9                     <ControlTemplate TargetType="{x:Type Button}">
10                         <StackPanel Orientation="Horizontal" VerticalAlignment="Center" >
11                             <TextBlock Name="Icon"
12                                          Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path= Content}"
13                                          FontSize="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path= FontSize}"
14                                   />
15                         </StackPanel>
16                         <ControlTemplate.Triggers>
17                                 <Trigger Property="IsMouseOver" Value="True" >
18                                 <Setter Property="Background" Value="Transparent" TargetName="Icon" ></Setter>
19                                 <Setter Property="Foreground" Value="Gray" TargetName="Icon"></Setter>
20                                 </Trigger>
21                                 <Trigger Property="IsPressed" Value="True" >
22                                 <Setter Property="Background" Value="Transparent" TargetName="Icon" ></Setter>
23                                 <Setter Property="Foreground" Value="DarkGray" TargetName="Icon" ></Setter>
24                                 </Trigger>
25                         </ControlTemplate.Triggers>
26                     </ControlTemplate>
27                 </Setter.Value>
28             </Setter>
29
30         </Style>

样式

2. 布局 这里有一个像素的boder

 1  <Border BorderThickness="1,1,1,1" BorderBrush="Black">
 2     <Grid>
 3         <Grid.RowDefinitions>
 4             <RowDefinition Height="30"></RowDefinition>
 5             <RowDefinition Height="*"></RowDefinition>
 6         </Grid.RowDefinitions>
 7         <Grid Grid.Row="0" Background="YellowGreen"  MouseMove="HeaderMouseMove" MouseDown="HeaderMouseDown">
 8             <Grid Height="{Binding Height, RelativeSource={RelativeSource TemplatedParent}}"
 9                 Width="{Binding Width, RelativeSource={RelativeSource TemplatedParent}}" Margin="0,0,0,0">
10                 <Grid.ColumnDefinitions>
11                     <ColumnDefinition Width="*"/>
12                     <ColumnDefinition Width="Auto"/>
13                 </Grid.ColumnDefinitions>
14                 <StackPanel Orientation="Horizontal" Grid.Column="0" Grid.ColumnSpan="2"  >
15                     <Image Source="Resources/icon.png" Width="20" Height="20" Margin="4,0,0,0"></Image>
16                     <TextBlock x:Name="CustomTitle" Text="标题要长一定要长" FontSize="14"
17                                Margin="4,0,0,0" VerticalAlignment="Center" />
18                 </StackPanel>
19                 <StackPanel Orientation="Horizontal" Grid.Column="2" Margin="0,4,4,4" >
20                     <Button Content="" Style="{StaticResource ButtonIconStyle}"  FontSize="20"    Click="MinClick"  />
21                         <Button Content=""  Style="{StaticResource ButtonIconStyle}" FontSize="16"  Click="MaxClick" />
22                         <Button Content=""  Style="{StaticResource ButtonIconStyle}" FontSize="20"  Click="CloseClick" RenderTransformOrigin="0.52,0.273"/>
23                 </StackPanel>
24             </Grid>
25         </Grid>
26        <Grid Grid.Row="1"></Grid>
27     </Grid>
28     </Border>

布局

3. C#代码实现

  • 采用win32函数获取鼠标位置
  •  1  /// <summary>
     2         /// 获取鼠标的坐标
     3         /// </summary>
     4         /// <param name="lpPoint">传址参数,坐标point类型</param>
     5         /// <returns>获取成功返回真</returns>
     6         [DllImport("user32.dll", CharSet = CharSet.Auto)]
     7         public static extern bool GetCursorPos(out POINT pt);
     8         public struct POINT
     9         {
    10             public int X;
    11             public int Y;
    12             public POINT(int x, int y)
    13             {
    14                 this.X = x;
    15                 this.Y = y;
    16             }
    17         }

    获取鼠标信息

  • 调整位置大小用到的类->网络获取

     1  public enum HitTest : int
     2     {
     3         HTERROR = -2,
     4         HTTRANSPARENT = -1,
     5         HTNOWHERE = 0,
     6         HTCLIENT = 1,
     7         HTCAPTION = 2,
     8         HTSYSMENU = 3,
     9         HTGROWBOX = 4,
    10         HTSIZE = HTGROWBOX,
    11         HTMENU = 5,
    12         HTHSCROLL = 6,
    13         HTVSCROLL = 7,
    14         HTMINBUTTON = 8,
    15         HTMAXBUTTON = 9,
    16         HTLEFT = 10,
    17         HTRIGHT = 11,
    18         HTTOP = 12,
    19         HTTOPLEFT = 13,
    20         HTTOPRIGHT = 14,
    21         HTBOTTOM = 15,
    22         HTBOTTOMLEFT = 16,
    23         HTBOTTOMRIGHT = 17,
    24         HTBORDER = 18,
    25         HTREDUCE = HTMINBUTTON,
    26         HTZOOM = HTMAXBUTTON,
    27         HTSIZEFIRST = HTLEFT,
    28         HTSIZELAST = HTBOTTOMRIGHT,
    29         HTOBJECT = 19,
    30         HTCLOSE = 20,
    31         HTHELP = 21,
    32     }

    HitTest

  • 主要C#代码,很少很简单

      1         private const int WM_NCHITTEST = 0x0084;
      2         private readonly int agWidth = 8; //拐角宽度
      3         private readonly int bThickness = 2; // 边框宽度
      4         private Point mousePoint = new Point(); //鼠标坐标
      5
      6         protected override void OnSourceInitialized(EventArgs e)
      7         {
      8             base.OnSourceInitialized(e);
      9             HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
     10             if (hwndSource != null)
     11             {
     12                 hwndSource.AddHook(new HwndSourceHook(this.WndProc));
     13             }
     14         }
     15
     16         protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
     17         {
     18             switch (msg)
     19             {
     20                 case WM_NCHITTEST:
     21                     #region 测试鼠标位置
     22                     if (WindowState == WindowState.Normal)
     23                     {
     24                         this.mousePoint.X = (lParam.ToInt32() & 0xFFFF);
     25                         this.mousePoint.Y = (lParam.ToInt32() >> 16);
     26                         // 窗口左上角
     27                         if (this.mousePoint.Y - this.Top <= this.agWidth
     28                             && this.mousePoint.X - this.Left <= this.agWidth)
     29                         {
     30                             handled = true;
     31                             return new IntPtr((int) HitTest.HTTOPLEFT);
     32
     33                         }
     34                         // 窗口左下角
     35                         else if (this.ActualHeight + this.Top - this.mousePoint.Y <= this.agWidth
     36                                  && this.mousePoint.X - this.Left <= this.agWidth)
     37                         {
     38                             handled = true;
     39                             return new IntPtr((int) HitTest.HTBOTTOMLEFT);
     40                         }
     41                         // 窗口右上角
     42                         else if (this.mousePoint.Y - this.Top <= this.agWidth
     43                                  && this.ActualWidth + this.Left - this.mousePoint.X <= this.agWidth)
     44                         {
     45                             handled = true;
     46                             return new IntPtr((int) HitTest.HTTOPRIGHT);
     47                         }
     48                         // 窗口右下角
     49                         else if (this.ActualWidth + this.Left - this.mousePoint.X <= this.agWidth
     50                                  && this.ActualHeight + this.Top - this.mousePoint.Y <= this.agWidth)
     51                         {
     52                             handled = true;
     53                             return new IntPtr((int) HitTest.HTBOTTOMRIGHT);
     54                         }
     55                         // 窗口左侧
     56                         else if (this.mousePoint.X - this.Left <= this.bThickness)
     57                         {
     58                             handled = true;
     59                             return new IntPtr((int) HitTest.HTLEFT);
     60                         }
     61                         // 窗口右侧
     62                         else if (this.ActualWidth + this.Left - this.mousePoint.X <= this.bThickness)
     63                         {
     64                             handled = true;
     65                             return new IntPtr((int) HitTest.HTRIGHT);
     66                         }
     67                         // 窗口上方
     68                         else if (this.mousePoint.Y - this.Top <= this.bThickness)
     69                         {
     70                             handled = true;
     71                             return new IntPtr((int) HitTest.HTTOP);
     72                         }
     73                         // 窗口下方
     74                         else if (this.ActualHeight + this.Top - this.mousePoint.Y <= this.bThickness)
     75                         {
     76                             handled = true;
     77                             return new IntPtr((int) HitTest.HTBOTTOM);
     78                         }
     79                     }
     80                     //else // 窗口移动
     81                     //{
     82                     //    handled = true;
     83                     //    return new IntPtr((int)HitTest.HTCAPTION);
     84                     //}
     85                     break;
     86
     87                     #endregion
     88             }
     89             return IntPtr.Zero;
     90         }
     91
     92         private void HeaderMouseMove(object sender, MouseEventArgs e)
     93         {
     94
     95             if (e.LeftButton == MouseButtonState.Pressed)
     96             {
     97
     98                 if (this.WindowState == WindowState.Maximized)
     99                 {
    100                     POINT px;
    101                     GetCursorPos(out px);
    102                     this.WindowState = WindowState.Normal;
    103                     Point p = e.GetPosition(sender as IInputElement);
    104                     double x = SystemParameters.WorkArea.Width;//得到屏幕工作区域宽度
    105                     this.Left = px.X - (p.X/x)*this.Width;
    106                     this.Top = px.Y - 5;
    107
    108                 }
    109                 else
    110                     this.DragMove();
    111             }
    112         }
    113
    114         private void MinClick(object sender, RoutedEventArgs e)
    115         {
    116            this.WindowState= WindowState.Minimized;
    117         }
    118
    119         private void MaxClick(object sender, RoutedEventArgs e)
    120         {
    121             if (this.WindowState == WindowState.Maximized)
    122             {
    123                 this.WindowState = WindowState.Normal;
    124             }
    125             else
    126             {
    127                 this.WindowState = WindowState.Maximized;
    128
    129             }
    130         }
    131
    132         private void CloseClick(object sender, RoutedEventArgs e)
    133         {
    134             this.Close();
    135         }
    136
    137         private void HeaderMouseDown(object sender, MouseButtonEventArgs e)
    138         {
    139             if (e.ClickCount == 2)
    140             {
    141                 this.WindowState = this.WindowState == WindowState.Maximized
    142                     ? WindowState.Normal
    143                     : WindowState.Maximized;
    144             }
    145         }

    功能主要cs代码

时间: 2024-10-13 13:40:02

实现的WPF外边框窗体的相关文章

WPF 无边框窗体

第一步:去掉那些最大化最小化和关闭 代码如下: WindowStyle="None" 第二步:去掉那边框 代码如下: AllowsTransparency="True" 第三步:拖动窗体 方法:给窗体设置MouseLeftButtonDown事件 代码如下: (1)前台代码: MouseLeftButtonDown="Border_MouseLeftButtonDown_1" (2)后台代码: private void Border_MouseL

01.WPF中制作无边框窗体

[引用:]http://blog.csdn.net/johnsuna/article/details/1893319 众所周知,在WinForm中,如果要制作一个无边框窗体,可以将窗体的FormBorderStyle属性设置为None来完成.如果要制作成异形窗体,则需要使用图片或者使用GDI+自定义绘制. 那么,在WPF中,我们怎样制作一个无边框窗体呢? 答案是将Window的WindowStyle属性设置为None,即WindowStyle="None" .如果是非矩形的异形窗体,则

利用WPF创建含多种交互特性的无边框窗体

咳咳,标题一口气读下来确实有点累,让我先解释一下.另外文章底部有演示程序的下载. 本文介绍利用WPF创建一个含有以下特性的窗口: 有窗口阴影,比如QQ窗口外围只有几像素的阴影: 支持透明且无边框,为了自行美化窗口通常都会想到使用无边框窗口吧: 可正常最大化,WPF无边框窗口直接最大化会直接使窗口全屏即会将任务栏一并盖住: 窗口边缘改变窗口大小,可以拖动窗口边缘改变大小: 支持等同于标题栏的全窗口空白区拖动,这一特性可以参考QQ: 支持多显示器环境. 上述针对无边框窗口的特性均可以独立实现,本文将

WPF添加外边框,添加外边框虚线

<Border Background="LightBlue" BorderBrush="Black"  BorderThickness="2" Margin="0,0,-6.2,-2.6" Padding="10">  外边框 <Grid> <Rectangle  Fill="white" RadiusX="10" RadiusY=&qu

WPF无边框可拖动窗体

下面主要记录下创建无边框窗体,并且可以拖动.这种窗体主要用于弹出小窗体时. <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http

WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案

首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如  WPF中不规则窗体与WebBrowser控件的兼容问题解决办法.该网友的解决办法也是别出心裁的,为什么这样说呢,你下载了他的程序认真读一下就便知道,他的webBrowser控件的是单独放在一个Form中,让这个Form与WPF中的一个Bord控件进行关联,进行同步移动,但是在移动的时候会出现闪烁,并且还会出现运动的白点,用户体验肯定不好. OK,

Qt:移动无边框窗体(使用Windows的SendMessage)

移动无边框窗体的代码网上很多,其原理都是一样的,但是是有问题的,我这里只是对其修正一下 网上的代码仅仅实现了两个事件 [cpp] view plain copy void EditDialog::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_DragPosition = event->globalPos() - this->pos(); event->accept()

【Qt】移动无边框窗体

分类: Qt2013-05-08 22:55 3027人阅读 评论(7) 收藏 举报 移动无边框窗体的代码网上很多,其原理都是一样的,但是是有问题的,我这里只是对其修正一下 网上的代码仅仅实现了两个事件 [cpp] view plaincopy void EditDialog::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_DragPosition = event->global

[WPF自定义控件]?Window(窗体)的UI元素及行为

原文:[WPF自定义控件]?Window(窗体)的UI元素及行为 1. 前言 本来打算写一篇<自定义Window>的文章,但写着写着发觉内容太多,所以还是把使用WindowChrome自定义Window需要用到的部分基础知识独立出来,于是就形成了这篇文章. 无论是桌面编程还是日常使用,Window(窗体)都是最常接触的UI元素之一,既然Window这么重要那么多了解一些也没有坏处. 2.标准Window 这篇文章主要讨论标准的Window,不包括奇形怪状的无边框.非矩形Window,即只讨论W