實現的WPF外邊框窗體

来源:http://www.cnblogs.com/hda37210/archive/2016/01/15/5133896.html
-Advertisement-
Play Games

最近看了一下wpf 越發喜歡. 邊看邊學,順便做點東西. WPF 的窗體有點醜.就自己做個窗體,當學習的demo吧 效果圖:實現功能: 最大化;最小化;關閉;按鈕三態; 標題欄拖動;雙擊標題欄最大化或者還原;滑鼠在窗體邊緣拖動可調整窗體大小;1. 右上角三個按鈕採用樣式實現效果 1 樣式2...


 最近看了一下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代碼

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 來源:http://zxlovenet.cnblogs.com 偽彩色處理是指將灰度圖像轉換成彩色圖象。因為人眼對於彩色的分辨能力遠高於對灰度圖像的分辨能力,所以將灰度圖像轉換成彩色可以提高人眼對圖像細節的辨別能力。偽彩色並不能真實的反映圖像像的彩色情況。 效果圖: 強度分層法和灰度級-彩色...
  • 1. 日期控制項的使用(如下圖所示,點擊空白處彈出日曆) (1)首先下載AjaxControlToolkit.dll(2)文件起始處添加下麵的語句(3)再添加下麵的語句2. 樣例
  • //可以上傳圖片,txt文檔。doc,wps,還有音頻文件,視屏文件等,功能強大啊!//前臺代碼片,設置上傳圖片的界面 //後臺代碼 ,實現圖片從客戶...
  • 原文鏈接:http://docs.autofac.org/en/latest/getting-started/index.html在程式中使用Autofac的基本模式是:用控制反轉(IoC)的思想組織程式。添加對 Autofac 的引用。程式啟動階段創建 ContainerBuilder。註冊組件。...
  • 以前寫過一個wp8的工程,說實話那會的代碼很麻煩,寫起來費勁,另外還沒多少人下載,不過到windows 10 開始微軟出了UWP架構以後一切都像以前的winform wpf一樣好轉起來,新建一個工程以後模板很簡潔。現在就開始介紹一下基本控制項的使用,為新手寫程式提供一個例子。7天酒店沒有官方客戶端.....
  • 貨位是ERP系統總的倉庫管理中必不可少的,倉庫是有貨架組成,貨架上的每個格子就是一個貨位,所有貨位上的商品的庫存總和就是倉庫商品的庫存。倉庫的貨位主要分為貨架和托盤,貨架就是倉庫的固定貨位,托盤就是移動貨位,或者稱為移動托盤。倉庫的貨位類型可以分為存貨位,揀貨貨位,移動貨位三種大的類型。按正殘品.....
  • 上周六我發表的文章《分享我基於NPOI+ExcelReport實現的導入與導出EXCEL類庫:ExcelUtility》受到了大家的熱烈支持與推薦,再此表示感謝,該ExcelUtility類庫自上次發文起,又經過了多次的改進,增加了許多的功能與方法,可以全面滿足大家的需求,下麵先來看一下新方法的測試...
  • 採購商品入庫完成後,下一步就是上架操作。所謂上架就是把入庫放到移動托盤的商品轉移到固定貨架上,貨架上有貨位號,可以把商品放到指定的貨位上。主要分兩步操作,上架操作主要是移動PDA上完成的 1.掃描移動托盤號 2.掃描上架貨位 上架的貨位是揀貨位或者存貨位,先掃描貨位號,然後掃...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...