你的位置:首页 > ASP.net教程

[ASP.net教程]实现的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         else110           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       else126       {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.Maximized142           ? WindowState.Normal143           : WindowState.Maximized;144       }145     }

    功能主要cs代码