• 实现的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="&#xE601;" Style="{StaticResource ButtonIconStyle}"  FontSize="20"    Click="MinClick"  />
    21                         <Button Content="&#xE602;"  Style="{StaticResource ButtonIconStyle}" FontSize="16"  Click="MaxClick" />
    22                         <Button Content="&#xE600;"  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代码
  • 相关阅读:
    aptana中删除空行
    css预处理的引入与问题
    rsyslog 服务器重启后 发现不能接受到外部日志 只能接受本地日志 关闭防火墙即可
    php访问其他网站接口
    mysql 表查询结果 总行数计算
    linux centos 恢复 还原 备份 Snapper 快照说明
    linux 服务 启动 关闭 列表
    linux yum 安装 卸载
    php7 mysql_pconnect() 缺失 解决方法
    搭建一个免费的,无限流量的Blog----github Pages和Jekyll入门
  • 原文地址:https://www.cnblogs.com/hda37210/p/5133896.html
Copyright © 2020-2023  润新知