You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为.NET 8 WPF桌面应用配置PerMonitor DpiAwareness实现跨屏UI缩放?

.NET 6+ WPF 跨显示器自动DPI缩放完整实现

一、修正项目配置(*.csproj)

你之前设置的Switch.System.Windows.DoNotScaleForDpiChanges=true是阻止WPF自动处理DPI变化的核心原因,先将其改为false,同时添加高DPI模式配置:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net6.0-windows</TargetFramework>
    <UseWPF>true</UseWPF>
    <!-- 启用Per-Monitor V2 DPI感知,实现跨显示器自适应 -->
    <ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
  </PropertyGroup>

  <ItemGroup>
    <!-- 允许WPF自动处理DPI变化 -->
    <RuntimeHostConfigurationOption Include="Switch.System.Windows.DoNotScaleForDpiChanges" Value="false" />
    <RuntimeHostConfigurationOption Include="Switch.System.IO.UseLegacyPathHandling" Value="false" />
  </ItemGroup>
</Project>

二、App.xaml 基础配置

保持Application的基础结构即可:

<Application x:Class="WpfDpiScaleDemo.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

三、App.xaml.cs 全局DPI兜底处理

在应用启动时确保DPI感知模式生效:

using System;
using System.Windows;
using Windows.Win32.PInvoke;

namespace WpfDpiScaleDemo
{
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            // 兜底设置PerMonitorV2模式,避免项目配置未生效的情况
            var currentProcess = System.Diagnostics.Process.GetCurrentProcess();
            SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);

            base.OnStartup(e);
        }
    }
}

四、主窗口布局(MainWindow.xaml)

使用相对布局容器,避免固定像素尺寸,确保控件随DPI自适应:

<Window x:Class="WpfDpiScaleDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DPI自适应演示"
        WindowStartupLocation="CenterScreen">
    <Grid Margin="20">
        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
            <TextBlock Text="跨显示器DPI自适应测试" FontSize="24" Margin="0 0 0 10"/>
            <Button Content="点击测试" Width="120" Height="40" FontSize="14"/>
            <TextBlock x:Name="DpiInfoText" Margin="0 10 0 0"/>
        </StackPanel>
    </Grid>
</Window>

五、主窗口DPI事件处理(MainWindow.xaml.cs)

监听窗口DPI变化,更新UI状态:

using System;
using System.Windows;
using System.Windows.Media;

namespace WpfDpiScaleDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            UpdateDpiInfo();
            // 绑定DPI变化事件
            this.DpiChanged += MainWindow_DpiChanged;
        }

        private void MainWindow_DpiChanged(object sender, DpiChangedEventArgs e)
        {
            UpdateDpiInfo();
            // 自定义控件需要手动调整的逻辑可在此添加
        }

        private void UpdateDpiInfo()
        {
            var dpiScale = VisualTreeHelper.GetDpi(this);
            DpiInfoText.Text = $"当前DPI缩放比例: {dpiScale.DpiScaleX:P0}";
        }
    }
}

关键注意事项

  • PerMonitorV2是WPF跨显示器自适应的最优模式,支持窗口在不同DPI显示器间移动时自动缩放。
  • 禁止使用固定Width/Height的布局方式,优先用Grid、StackPanel等相对布局容器,控件尺寸用*或Auto。
  • 字体大小尽量使用相对单位,WPF默认字体会自动随DPI缩放。
  • 第三方控件需确保支持Per-Monitor DPI感知,否则可能出现缩放异常。

内容的提问来源于stack exchange,提问作者wpf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 18:44:56