概述
?在WPF界面開發中,系統默認的窗口比較丑,有時候想自定義窗體,比如微信的客戶端窗口這樣:使得左邊的一塊頂到最上端,如下圖所示:
這時候我們可以 WindowStyle="None",AllowsTransparency="True"去掉默認的窗體邊框,然后添加最小最大和關閉的按鈕,然后重寫相關的功能實現
<TextBlock?x:Name="lblTitle"?Text="自定義窗體"?Foreground="White"?FontSize="14"?Margin="10?0?0?0"?VerticalAlignment="Center"/><StackPanel Orientation="Horizontal" HorizontalAlignment="Right"><Button WindowChrome.IsHitTestVisibleInChrome="True" Name="button_MiniSize" Content="─" Style="{StaticResource btn_nap}" HorizontalAlignment="Right" Foreground="White" Margin="0 0 5 0" Height="30" Width="30"/><Button WindowChrome.IsHitTestVisibleInChrome="True" Name="button_MaxSize" Content="?" Style="{StaticResource btn_nap}" HorizontalAlignment="Right" Foreground="White" Margin="0 0 5 0" Height="30" Width="30"/><Button WindowChrome.IsHitTestVisibleInChrome="True" x:Name="btn_Close" Content="?" Style="{StaticResource btn_nap}" HorizontalAlignment="Right" Foreground="White" Margin="0 0 5 0" Height="30" Width="30"/></StackPanel>
但是這樣做的話,這就不貼近原生窗口體驗了,
-. 需要寫大量代碼實現Window本來的拖動、改變大小、最大化最小化等行為;
-. 各種其它細節的修改,比如:最大化會覆蓋任務欄等;
為了保持最大的原生的同時以少量代碼實現自定義窗體,我們使用WindowChrome去實現會更加便捷和優雅.
WindowChrome用法舉例
<Window x:Class="WpfApp13.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp13"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800" Background="{x:Null}" FontWeight="ExtraLight" ResizeMode="CanResize" WindowStartupLocation="CenterScreen"><Window.Style><Style TargetType="Window"><Setter Property="WindowChrome.WindowChrome"><Setter.Value><WindowChromeCornerRadius="0"CaptionHeight="30"GlassFrameThickness="-1"UseAeroCaptionButtons="True"NonClientFrameEdges="None"/></Setter.Value></Setter>
</Style></Window.Style><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="Auto"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><Image Source="left1.png" Stretch="Fill"/><Grid Grid.Column="1" ><Grid.RowDefinitions><RowDefinition Height="40"/><RowDefinition Height="32"/><RowDefinition Height="*"/></Grid.RowDefinitions><Grid Grid.Row="0" ><Menu Margin="2,8,200,0" VerticalAlignment="Center" WindowChrome.IsHitTestVisibleInChrome="True" Background="Transparent"><MenuItem Header="C#技術交流⑥群(111)" FontSize="15" /></Menu></Grid><Grid Grid.Row="2"><TextBlockHorizontalAlignment="Center"VerticalAlignment="Center"FontSize="50"FontWeight="Bold"Foreground="blue"Text="呆萌氣質小可愛" /></Grid></Grid></Grid>
</Window>
運行結果:
WindowChrome用法說明
UseAeroCaptionButtons:表示標題欄上的那三個默認按鈕是否可以命中,這里設置為true,如果要自己管理則設置為false。
GlassFrameThickness和ResizeBorderThickness:這兩個屬性用于控制邊框,及用戶可以單擊并拖動以調整窗口大小的區域的寬度;其中GlassFrameThickness用來設置距離區域的厚度,設置為-1,可以使得區域覆蓋整個界面;ResizeBorderThickness可以設置窗口縮放的邊框厚度,不宜設置過大。
CaptionHeight:指定WindowChrome的標題欄高度;我這里設置的是30。設置為0表示界面無法響應鼠標的任何操作(拖動窗口, 雙擊標題欄的最大化最小化。。。僅僅是行為區域,并不影響外觀)。
NonClientFrameEdges:即指定哪一邊不屬于客戶區。用法舉例:
<WindowChrome.WindowChrome><WindowChrome NonClientFrameEdges="Left,Bottom,Right" />
</WindowChrome.WindowChrome>
要使用WindowChrome,最簡潔語法如下:
<WindowChrome.WindowChrome><WindowChrome /></WindowChrome.WindowChrome>
然后得到的窗體擁有默認窗口的所有窗口行為,
此外需要注意的是,如果元素在CaptionHeight的高度內,是無法響應鼠標事件的,此時需要給元素設置屬性WindowChrome.IsHitTestVisibleInChrome="True",很常見的問題,在自定義標題按鈕的時候,會發現自己點擊不了標題按鈕!
源碼下載
鏈接:https://pan.baidu.com/s/1ilUXW3JzrCLQX2xFINmByw
提取碼:6666