C# 如何对WPF应用程序启用DPI感知,并根据屏幕分辨率对其进行缩放

C# 如何对WPF应用程序启用DPI感知,并根据屏幕分辨率对其进行缩放,c#,wpf,xaml,screen-resolution,dpi,C#,Wpf,Xaml,Screen Resolution,Dpi,在日常生活中,我们必须处理许多不同类型的显示器尺寸,可能是移动的,也可能是4k显示器。屏幕分辨率因显示器而异。这里的另一个重要因素是DPI(每英寸显示),它主要是windows中的比例因子,但与屏幕分辨率有很大关系 现在我给你一个例子,首先假设我在全高清显示器上运行VisualStudio应用程序,分辨率是1920x1080。假设我将显示分辨率从全高清(1920x1080)更改为1366x768。之后,我在同一个显示器上再次运行VisualStudio,我看到用户界面(UI)稍微变大了,所有控件

在日常生活中,我们必须处理许多不同类型的显示器尺寸,可能是移动的,也可能是4k显示器。屏幕分辨率因显示器而异。这里的另一个重要因素是DPI(每英寸显示),它主要是windows中的比例因子,但与屏幕分辨率有很大关系

现在我给你一个例子,首先假设我在全高清显示器上运行VisualStudio应用程序,分辨率是1920x1080。假设我将显示分辨率从全高清(1920x1080)更改为1366x768。之后,我在同一个显示器上再次运行VisualStudio,我看到用户界面(UI)稍微变大了,所有控件、文本、图标和按钮都根据当前显示器DPI的缩放比例和分辨率完全对齐

当我们以较低的分辨率运行VisualStudio和其他windows应用程序时,UI应该会变得更大

我想在我的WPF应用程序中应用类似的效果,这样每当屏幕分辨率和DPI改变时,我的应用程序都会根据显示DPI和分辨率自动调整。我已经尝试了Microsoft per monitor DPI aware for windows 10,并根据GitHub说明编辑app.Mainfest文件和取消注释一些代码,但在我的情况下没有任何效果

我还绑定了屏幕分辨率和我的应用程序的高度和宽度,但它覆盖了整个屏幕,我不希望这样

但我明白的一件事是,我必须获得系统DPI,然后将其应用于我的窗口加载事件,但我不知道如何在代码中做到这一点

这里是MainWindow.xaml代码(我只放了少量代码,因为它是office项目)


设置
账户
这是我的后端c#逻辑代码MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void myMainWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DragMove();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
命名空间WpfApp1
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
私有void mymain窗口\u MouseLeftButtonDown(对象发送器,MouseButtonEventArgs e)
{
DragMove();
}
}
}
另一个重要的因素是我也使用了视图框,但它并没有像我想要的那样工作。有人告诉我,我应该使用流体布局,我应该使用Grid.RowDefinitions和Grid.ColumnDefinitions,我还使用*和Auto调整大小,而不是使用绝对定位,我应该使用边距和填充。我知道这是一个问题,但我的主要问题是关于新闻部和决议,这与绝对定位无关

我应该在我的主网格上使用缩放变换,这应该和DPI装饰器和分辨率绑定在一起,但我没有足够的想法知道如何做到这一点

正如我前面所说的,视图框不起作用,因为我在应用程序中使用了Seoge UI字体,如果您仔细查看我的MainWindow.xaml代码,您会看到我给出了font size=10,因为后者在这个大小下的形状非常好,我还使用TextOptions.textformatingmode=“Display”进行UI设计

我的问题是我的WPF应用程序如何根据自身自动检测屏幕DPI和分辨率以及完美的缩放变换,从而避免字体模糊问题或主窗口非常小等等。
完美贴合、缩放,根据显示效果美观。

WPF在默认情况下已支持DPI。见第一份副本。可能您真正想问的是如何根据窗口大小缩放UI元素。实现这一点的主要机制是
ViewBox
。参见第二份和第三份副本。如果您在查看这些详细信息后仍然需要帮助,请发布一个新问题,在该问题中,您提供了一个适当的、清晰、简洁的解释,说明该代码的功能、与您想要的不同之处,以及您需要帮助的具体内容。@PeterDuniho这不是任何重复的问题。我尝试了所有这些,但没有一个有效。你不明白我的问题我想说什么。我的简短问题是,在较低的分辨率下,一些WPF应用程序会自动缩放以匹配系统DPI。举个例子,以较低的分辨率运行VisualStudio应用程序,您会看到VisualStudio用户的交错正在改变,图标和文本变得更大。我想在我的申请中加入这个。如果你已经有一个演示应用程序,那么你可以给我一个下载链接。“举个例子,以较低的分辨率运行visual studio应用程序,你会看到visual studio用户的交错变化,图标和文本变大了。我想在我的应用程序中使用它”--这与DPI感知相反。DPI aware的全部要点是,当分辨率发生变化时,UI不会发生根本性的变化。不支持DPI的应用程序最终会根据分辨率上下伸缩(分辨率越高,它们越小)。在任何情况下,不要使用注释进行澄清。修正问题或发布新问题。“您的评论中不能包含任何内容。@彼得杜尼奥对不起,先生。你说这与DPI aware完全相反。我希望你明白我的问题是什么。现在告诉我那是什么?为什么在分辨率较低的应用程序中会出现这样的行为?可能是我混淆了这个概念。先生,请帮帮我。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void myMainWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DragMove();
        }
    }
}