最近看了一下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代码
posted on 2016-01-15 17:42  不惜  阅读(4967)  评论(2编辑  收藏  举报