WPF中设置Canvas.Left后图片超出画布,如何获取真实屏幕尺寸?
问题:WPF中Canvas尺寸与屏幕真实分辨率不匹配导致元素位置错误
我将Canvas尺寸设为19201080,添加一张200200的图片并希望它位于画布右上角,但执行以下代码后图片超出画布:
Image img = new Image(); img.Source = SOURCE; img.Width = 200; img.Height = 200; screen.Canvas.Children.Add(img); // 已提前创建screen对象和Canvas img.SetValue(Canvas.LeftProperty, 1720); img.SetValue(Canvas.TopProperty, 0);
手动测试发现设置Canvas.Left为1350时才适配,但无法理解原因。
Canvas位于窗口中,启动时最大化窗口,同时在窗口构造函数中执行以下代码最大化Canvas:
var resolution = Screen.PrimaryScreen.Bounds; Canvas.Width = resolution.Width; // Canvas是我的画布名称 Canvas.Height = resolution.Height;
后续发现获取的屏幕尺寸为1920x1080,但实际真实尺寸是1536x864,请教如何获取真实屏幕尺寸?
解决方案
问题根源在于Windows的DPI缩放,你通过Screen.PrimaryScreen.Bounds获取的是经过系统缩放后的像素尺寸,而非屏幕物理真实分辨率。以下是几种解决方式:
1. 用WPF原生API获取真实分辨率
// 计算真实物理像素尺寸 double realWidth = SystemParameters.PrimaryScreenWidth * SystemParameters.PrimaryScreenDpiX / 96; double realHeight = SystemParameters.PrimaryScreenHeight * SystemParameters.PrimaryScreenDpiY / 96; // 将真实尺寸应用到Canvas Canvas.Width = realWidth; Canvas.Height = realHeight;
注:96是Windows标准DPI值,通过当前屏幕DPI与标准值的比例,还原真实物理像素。
2. 通过Graphics类计算缩放比例
using System.Drawing; using System.Windows.Interop; // 获取屏幕DPI缩放因子 using (Graphics g = Graphics.FromHwnd(new WindowInteropHelper(this).Handle)) { float scaleX = g.DpiX / 96; float scaleY = g.DpiY / 96; // 从缩放后的尺寸反推真实物理尺寸 var scaledBounds = Screen.PrimaryScreen.Bounds; double realWidth = scaledBounds.Width / scaleX; double realHeight = scaledBounds.Height / scaleY; Canvas.Width = realWidth; Canvas.Height = realHeight; }
3. 更简便的元素定位方式
无需手动计算Canvas尺寸和图片Left值,直接让Canvas自动填充窗口,并通过Canvas.RightProperty定位图片:
- 在XAML中设置Canvas的对齐属性:
<Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> - 窗口启动时设置最大化:
this.WindowState = WindowState.Maximized; - 图片定位代码改为:
img.SetValue(Canvas.RightProperty, 0.0); img.SetValue(Canvas.TopProperty, 0.0);
这样图片会自动固定在Canvas右上角,不受屏幕缩放或窗口尺寸变化影响。
内容的提问来源于stack exchange,提问作者shayan bajelan
相关产品推荐
相关产品推荐

