WPF 不同DPI下,窗口大小的處理
阿新 • • 發佈:2018-10-23
his ble bsp 位置 location helper ren object 獲取
在設置桌面不同分辨率以及較大DPI下,窗口如何顯示的問題。(此例中僅設置高度)
前端:
- 設置窗口內容自適應SizeToContent="WidthAndHeight"
- 添加ViewBox -- 設置默認不拉伸Stretch="None",當DPI超大時如超過1920*1080p的175%(即win10默認不支持的比例顯示),開啟ViewBox縮放
- 頂層布局容器RootGrid添加高寬最大值和最小值。
1 <Window x:Class="WindowHeightChangedForDpi.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WindowHeightChangedForDpi" 7 mc:Ignorable="d" 8Title="MainWindow" SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen"> 9 <Viewbox x:Name="RootViewbox" Stretch="None"> 10 <Grid x:Name="RootGrid" Width="1000" MaxHeight="680" MinHeight="520" ClipToBounds="True"> 11 12 </Grid> 13 </Viewbox> 14</Window>
後臺:
- 添加對Loaded事件的監聽,並在之後註銷。窗口只需要首次初始其高度即可。
- 獲取屏幕的高度和任務欄的高度 -- 具體可以參考C# 獲取當前屏幕的寬高和位置
- 比較當前可顯示高度(屏幕高度-任務欄高度)與窗口的最大/最小高度,然後設置當前窗口的實際高度。
- 如果可顯示高度比最小值還小,則開啟ViewBox內容縮放。ViewBox的高度為當前可顯示高度。
- 如果當前窗口有陰影,可設置陰影高度大小。保證窗口在可顯示區域內正常顯示。
1 public partial class MainWindow : Window 2 { 3 public MainWindow() 4 { 5 InitializeComponent(); 6 Loaded += InitWindowActualHeight_OnLoaded; 7 } 8 9 #region 設置窗口對屏幕高度的自適應 10 11 private void InitWindowActualHeight_OnLoaded(object sender, RoutedEventArgs e) 12 { 13 Loaded -= InitWindowActualHeight_OnLoaded; 14 InitWindowActualHeight(); 15 } 16 17 private const double WindowShadowHeight = 0; 18 19 private void InitWindowActualHeight() 20 { 21 //獲取任務欄高度 22 var taskbarHeight = SystemParameters.PrimaryScreenHeight - SystemParameters.WorkArea.Height; 23 //獲取窗體所在屏幕的高度 24 var height = GetScreenHeight(); 25 var visibleAreaHeight = height - taskbarHeight; 26 27 //可顯示高度 > 窗口最大高度 28 if (visibleAreaHeight > RootGrid.MaxHeight + WindowShadowHeight) 29 { 30 //設置高度等於最大高度 31 RootGrid.Height = RootGrid.MaxHeight; 32 } 33 //可顯示高度 < 窗口最小高度 34 else if (visibleAreaHeight < RootGrid.MinHeight + WindowShadowHeight) 35 { 36 //設置Viewbox高度=可視高度-陰影高度(此處通過綻放顯示窗口,所以不能通過設置窗口或者設置內容的高度來實現) 37 RootViewbox.Height = visibleAreaHeight - WindowShadowHeight; 38 //等比例縮小 39 RootViewbox.Stretch = Stretch.Uniform; 40 } 41 else 42 { 43 //設置高度等於最小高度 44 RootGrid.Height = RootGrid.MinHeight; 45 } 46 } 47 const double DpiPercent = 96; 48 private double GetScreenHeight() 49 { 50 var intPtr = new WindowInteropHelper(this).Handle;//獲取當前窗口的句柄 51 var screen = Screen.FromHandle(intPtr);//獲取當前屏幕 52 53 double height = 0; 54 using (Graphics currentGraphics = Graphics.FromHwnd(intPtr)) 55 { 56 double dpiXRatio = currentGraphics.DpiX / DpiPercent; 57 double dpiYRatio = currentGraphics.DpiY / DpiPercent; 58 height = screen.Bounds.Height / dpiYRatio; 59 //var width = screen.Bounds.Width / dpiXRatio; 60 //var left = screen.Bounds.Left / dpiXRatio; 61 //var top = screen.Bounds.Top / dpiYRatio; 62 } 63 return height; 64 } 65 #endregion
註:獲取的屏幕高度為屏幕像素,需要轉換為WPF單位。
WPF 不同DPI下,窗口大小的處理