Как включить поддержку DPI для приложения WPF и масштабировать его в соответствии с разрешением экрана

в повседневной жизни нам приходится иметь дело с большим количеством различных типов дисплеев, это могут быть мобильные устройства или мониторы с разрешением 4k. Разрешение экрана варьируется от дисплея к дисплею. Здесь еще одним важным фактором является DPI (отображение на дюйм), который в основном является коэффициентом масштабирования в окнах, но имеет большое отношение к разрешению экрана.

Теперь я приведу вам пример. Сначала предположим, что я запускаю приложение Visual Studio на мониторе Full HD с разрешением 1920x1080. Предположим, я изменил разрешение экрана с Full HD (1920x1080) на 1366x768. И после этого я снова запускаю визуальную студию на том же дисплее и вижу, что пользовательский интерфейс (UI) стал немного больше, а все элементы управления, текст, значки и кнопки идеально выровнены в соответствии с текущим масштабированием и разрешением DPI монитора.

И пользовательский интерфейс должен стать больше, как это происходит, когда мы запускаем Visual Studio и другие приложения Windows с более низким разрешением.

Я хочу применить аналогичный эффект в своем приложении WPF, чтобы при каждом изменении разрешения экрана и DPI мое приложение автоматически настраивалось в соответствии с DPI и разрешением дисплея. Я уже пробовал Microsoft для каждого монитора с поддержкой DPI для Windows 10, редактировал файл app.Mainfest и раскомментировал некоторый код в соответствии с инструкциями GitHub, но в моем случае ничего не работает.

Я также привязываю разрешение экрана к высоте и ширине моего приложения, но оно покрывает весь экран, я этого не хочу.

Но я понимаю одну вещь: мне нужно получить системный DPI, а затем применить его к моему событию загрузки окна, но я не знаю, как это сделать в коде.

Вот код MainWindow.xaml (я добавил немного кода, потому что это офисный проект)

<Window
    x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfApp1"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Name="myMainWindow"
    Title="MainWindow"
    Width="1024"
    Height="547.4"
    AllowsTransparency="True"
    WindowStartupLocation="CenterScreen"
    WindowStyle="None"
    MouseLeftButtonDown="myMainWindow_MouseLeftButtonDown"
    mc:Ignorable="d">
    <Grid Name="MainGrid" Background="#282828">
        <Button
            x:Name="BtnSettings"
            Width="71"
            Height="24"
            Margin="165,14,0,0"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            RenderOptions.BitmapScalingMode="NearestNeighbor"
            RenderOptions.ClearTypeHint="Enabled"
            SnapsToDevicePixels="True"
            UseLayoutRounding="True">
            <Button.Content>
                <TextBlock
                    Margin="0,-2,0,0"
                    FontFamily="Segoe UI"
                    FontSize="10"
                    TextOptions.TextFormattingMode="Display"
                    UseLayoutRounding="True">
                    Settings
                </TextBlock>
            </Button.Content>
        </Button>
        <Button
            x:Name="BtnAccounts"
            Width="71"
            Height="24"
            Margin="237,14,0,0"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            RenderOptions.BitmapScalingMode="NearestNeighbor"
            RenderOptions.ClearTypeHint="Enabled"
            SnapsToDevicePixels="True"
            UseLayoutRounding="True">
            <Button.Content>
                <TextBlock
                    Margin="0,-2,0,0"
                    FontFamily="Segoe UI"
                    FontSize="10"
                    TextOptions.TextFormattingMode="Display"
                    UseLayoutRounding="True">
                    Accounts
                </TextBlock>
            </Button.Content>
        </Button>
    </Grid>
</Window>

И вот мой внутренний логический код С#, известный как 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();
        }
    }
}

Другим важным фактором является то, что я также использую окно просмотра, но оно не работает так, как я хотел. Некоторые люди говорили мне, что я должен использовать гибкий макет, и я должен использовать Grid.RowDefinitions и Grid.ColumnDefinitions, и я также использую * и Auto для изменения размера и не использую абсолютное позиционирование, а вместо этого я должен использовать Margin и padding. Я знаю, что это проблема, но моя главная проблема связана с DPI и разрешением, которые не имеют ничего общего с абсолютным позиционированием.

Я должен использовать преобразование масштаба в моей MainGrid, и это должно быть связано с декоратором DPI и разрешением, но у меня недостаточно идей, как это сделать.

Как я уже говорил ранее, это окно просмотра не работает, потому что я использую шрифт пользовательского интерфейса Seoge в своем приложении, и если вы внимательно посмотрите мой код MainWindow.xaml, то увидите, что я задаю размер шрифта = 10, потому что последние принимают очень хорошую форму в этот размер, и я также использую TextOptions.TextFormattingMode=Display для целей дизайна пользовательского интерфейса.

Мой вопрос заключается в том, как мое приложение WPF автоматически определяет DPI и разрешение экрана и идеально масштабирует преобразование в соответствии с самим собой, поэтому не возникает проблем с размытым шрифтом или главное окно очень маленькое и т. д. Идеально подходит, масштабируется и хорошо выглядит в соответствии с дисплеем.


person MERUN KUMAR MAITY    schedule 25.04.2021    source источник
comment
WPF уже по умолчанию поддерживает DPI. Смотрите первый дубликат. Вероятно, вы действительно спрашиваете, как масштабировать элементы пользовательского интерфейса в соответствии с размером окна. Основным механизмом для достижения этого является ViewBox. См., например. второй и третий дубликаты. Если вам все еще нужна помощь после просмотра этих деталей, опубликуйте новый вопрос, в котором вы предоставите правильный минимальный воспроизводимый пример, вместе с четким и кратким объяснением того, что делает этот код, чем он отличается от того, что вам нужно, и в чем конкретно вам нужна помощь.   -  person Peter Duniho    schedule 25.04.2021
comment
@PeterDuniho Это не повторяющийся вопрос. Я пробовал все это, но ни один из них не работает. Вы не поняли моего вопроса, что я хочу сказать. Мой краткий вопрос: в более низком разрешении некоторые приложения WPF автоматически масштабируются в соответствии с системным DPI. Возьмем, к примеру, запуск приложения Visual Studio в более низком разрешении, и вы увидите, что чередование пользователей Visual Studio меняется, а значок и текст становятся больше. Я хочу это в своем приложении. Если у вас уже есть демо-приложение, вы можете дать мне ссылку для скачивания.   -  person MERUN KUMAR MAITY    schedule 25.04.2021
comment
Возьмите пример: запустите приложение Visual Studio с более низким разрешением, и вы увидите, что чередование пользователей Visual Studio меняется, а значок и текст становятся больше. Я хочу, чтобы это было в моем приложении — это противоположность DPI-осведомленности. Весь смысл DPI-aware заключается в том, что пользовательский интерфейс не меняется принципиально при изменении разрешения. Приложения, которые не поддерживают DPI, масштабируются вверх и вниз в зависимости от разрешения (они становятся меньше при более высоких разрешениях). В любом случае, не используйте комментарии для пояснений. Исправьте вопрос или задайте новый. Вы не можете разместить минимально воспроизводимый пример в комментариях.   -  person Peter Duniho    schedule 25.04.2021
comment
@PeterDuniho извините, сэр. Вы говорите, что это полная противоположность DPI. Надеюсь, вы понимаете, в чем моя проблема. А теперь скажи мне, что это? Почему приложения с более низким разрешением ведут себя так? Может быть, я перепутал концепцию. Сэр, пожалуйста, помогите мне.   -  person MERUN KUMAR MAITY    schedule 25.04.2021
comment
docs.microsoft. com/en-us/windows/win32/hidpi/   -  person Peter Duniho    schedule 25.04.2021
comment
@PeterDuniho Большое спасибо, сэр. Не могли бы вы привести примеры кода? Я уже публикую свой XML-код MainWindow и код внутренней логики. Пожалуйста, опубликуйте ответ с вашим измененным кодом, чтобы я пометил ваш ответ как решенный.   -  person MERUN KUMAR MAITY    schedule 25.04.2021