很多應用需要定制化視窗,而視窗定制化不能繞過的一個問題是标題欄定制化。
基于wpf的視窗程式,一般會通過透明,去邊框化的方式将原有的标題欄遮擋。
預設情況下,wpf 視窗的标題欄是這樣的, 這時最化小,最大化/還原和關閉的行為都是
像正常windows程式的行為,不需要添加任何代碼。
設定 WindowStyle="None" 之後,标題欄的圖示,标題以及三個按鈕都不見了。但是标題欄的還留
下一步部分,如下所示
需要添加在視窗屬性中添加
AllowsTransparency="True" Background="Transparent" 才能隐藏這塊區域。整個視窗成了透明的
可以任任意定制的區域。
通過以下代碼定義我們自己想要的标題欄和客戶區域
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Background="Blue" x:Name="titleBar">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentControl ContentTemplate="{StaticResource Icon_CaptionFlyoutBtnHome}" Margin="10 0 0 0"/>
<TextBlock Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" Text="由你定制" Margin="10 0 0 0"/>
<Button x:Name="btnMin" Grid.Column="2" ToolTip="最小化" Width="30" Height="30" VerticalAlignment="Center" Style="{StaticResource PureImageButtonStyle}" ContentTemplate="{StaticResource Icon_minimize}"/>
<Button x:Name="btnRestore" Grid.Column="3" ToolTip="還原" Width="30" Height="30" Margin="10 0 0 0" VerticalAlignment="Center" Style="{StaticResource PureImageButtonStyle}" ContentTemplate="{StaticResource Icon_MinWnd}"/>
<Button x:Name="btnClose" Grid.Column="4" ToolTip="關閉" Width="30" Height="30" Margin="10 0 20 0" VerticalAlignment="Center" Style="{StaticResource PureImageButtonStyle}" ContentTemplate="{StaticResource Icon_close}"/>
</Grid>
<Border Grid.Row="1" Background="White">
<TextBlock VerticalAlignment="Center" Text="Add any content" HorizontalAlignment="Center"/>
</Border>
</Grid>
效果如下:
但是此時,這個标題欄除了樣子,還不具标題欄該有的可拖動、最小化,最大化/還原,關閉的功能。
為這三個按鈕加上事件以及整個工具欄的拖動事件。
視窗可以通過工具欄拖動了,最小化,半閉也正常,隻不過這個時候發現最大化時,視窗會将系統的
狀态欄擋住。
如果不考慮擴充屏,那麼可以在視窗的構造函數中通過添加以下代碼,限制視窗高度, 使最大化不至于
擋住系統工作列。
MaxHeight = SystemParameters.WorkArea.Height;
但是如果有擴充屏,當程式被拖曳到擴充屏時,那麼最大化依然會把護展屏的工作列覆寫。
這時候我們需要檢測程式是否在擴充屏上并作出來對應的處理。因為MaxHeight在運作過程動态改變不起效果。是以有擴充屏,即使能到擴充屏WorkArea.Height,簡單重設MaxHeight并沒有作用。是以最大化/還原就不能通過WindowState來實作。
這裡主要通過判斷目前視窗的大小與客戶區大小的關系來判斷視窗是否處于最大化,在非最大化的時候,儲存視窗的位置與大小,以便用于恢複。關鍵代碼如下
關于CustomizedToStateChanged的代碼,全部提供在此 https://download.csdn.net/download/mochounv/16072523
其中注意一點。 Winform下面與Screen的尺寸參數是像素值,是以并不能直接将得到size賦給wpf的視窗。