Проблема с разрешением экрана в WPF?

Я собираюсь определить разрешение с помощью следующего кода в WPF:

double height = System.Windows.SystemParameters.PrimaryScreenHeight;
double width = System.Windows.SystemParameters.PrimaryScreenWidth;

Текущее разрешение моего экрана 1920*1200, но height 960.0, а width 1536.0 !!!

Что с ним не так?
Заранее спасибо.


person Mohammad Dayyan    schedule 10.02.2010    source источник


Ответы (8)


Имейте в виду, что все местоположения и размеры WPF являются числами с плавающей запятой с единицей измерения 1/96 дюйма. Не пиксели. Это делает ваши оконные конструкции независимыми от разрешения. Делаем математику: рост = 960/96 = 10 дюймов. С вашим видеоадаптером, установленным на 120 точек на дюйм (120/96 = 125%): 10 * 120 = 1200 пикселей. То же самое по ширине: 1536/96 * 120 = 1920 пикселей.

System.Windows.Forms работает в единицах пикселей. Вы получаете меньше 1050 для высоты, потому что она вычитает высоту панели задач. Но для WPF вы всегда хотите работать с 1/96", а не с пикселями.

person Hans Passant    schedule 10.02.2010

Для еще более надежной реализации вам следует рассчитать коэффициенты DPI в вашей системе и работать с этими коэффициентами. Обычное значение DPI составляет 96, но некоторые мониторы могут иметь другие значения. Учтите, что ваш код может выполняться на мониторе с другим значением DPI, чем 96. Рассмотрим этот код:

    private static void CalculateDpiFactors()
    {
        Window MainWindow = Application.Current.MainWindow;
        PresentationSource MainWindowPresentationSource = PresentationSource.FromVisual(MainWindow);
        Matrix m = MainWindowPresentationSource.CompositionTarget.TransformToDevice;
        thisDpiWidthFactor = m.M11;
        thisDpiHeightFactor = m.M22;
    }

Затем вы можете использовать эти отношения, чтобы получить окончательные значения:

CalculateDpiFactors();
double ScreenHeight = SystemParameters.PrimaryScreenHeight * thisDpiHeightFactor;
double ScreenWidth = SystemParameters.PrimaryScreenWidth * thisDpiWidthFactor;

Значения ScreenHeight и ScreenWidth должны соответствовать тому, что вы видите в окне свойств вашего монитора.

person JeffFerguson    schedule 15.06.2010
comment
Это хорошо, но у вас есть окно заранее. Как рассчитать DPI без окна? Это должно быть возможно - dpi является свойством рабочего стола, а не только окна. - person greenoldman; 21.10.2010
comment
Спасибо, это было очень полезно. - person Vladimir Amiorkov; 16.12.2015
comment
Кажется, здесь есть некоторый код, связанный с этим: mesta-automation.com/ techniques-scaling-wpf-application - person Beachwalker; 27.03.2017

Пожалуйста, вызовите это после того, как ваши окна будут загружены.

 public static class Ext
{
    public static Size GetNativePrimaryScreenSize(this Window window)
    {
        PresentationSource mainWindowPresentationSource = PresentationSource.FromVisual(window);
        Matrix m = mainWindowPresentationSource.CompositionTarget.TransformToDevice;
        var dpiWidthFactor = m.M11;
        var dpiHeightFactor = m.M22;
        double screenHeight = SystemParameters.PrimaryScreenHeight * dpiHeightFactor;
        double screenWidth = SystemParameters.PrimaryScreenWidth * dpiWidthFactor;

        return new Size(screenWidth, screenHeight);
    }
}
person Andreas    schedule 16.02.2016

Попробуйте SystemParameters.FullPrimaryScreenWidth и FullPrimaryScreenHeight, я полагайте, что PrimaryScreenWidth и Height возвращают размер доступного окна клиента после удаления панели задач и других полос рабочего стола на вашем экране.

person Akash Kava    schedule 10.02.2010

вместо этого вы можете использовать это: http://msdn.microsoft.com/en-us/library/system.windows.forms.screen.primaryscreen.aspx

person Rob Fonseca-Ensor    schedule 10.02.2010
comment
Я проверил это, результат тот же, что и в первом моем посте! - person Mohammad Dayyan; 10.02.2010
comment
хорошо, это странно. Что произойдет, если вы измените разрешение экрана с панели управления? - person Rob Fonseca-Ensor; 10.02.2010
comment
Поменял разрешение на 1680*1050, результат: height = 1002.0 ; ширина=1680.0. Кстати: DPI составляет 125% - person Mohammad Dayyan; 10.02.2010

Если вы отметите «Использовать масштабирование DPI в стиле Windows XP», то возвращаемое значение «Screen.PrimaryScreen.Bounds» будет правильным. Если нет, возвращаемое значение пропорционально уменьшается на значение DPI (которое используется по умолчанию).

Чтобы найти флажок «Использовать масштабирование DPI в стиле Windows XP», разверните ссылку «Чтобы сделать текст и элементы на экране более четкими в программах, не предназначенных для высокого разрешения» по следующей ссылке: http://windows.microsoft.com/en-us/windows-vista/Make-the-text-on-your-screen-larger-or-smaller

person Marc G.    schedule 03.05.2012
comment
К вашему сведению: эта ссылка теперь автоматически ведет к объяснению Windows 8.x, а не XP/Vista/Win7. - person Clint StLaurent; 13.02.2014

Вы можете использовать это:

float dpiX, dpiY;
using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
{
     dpiX = graphics.DpiX;
     dpiY = graphics.DpiY;
}

double screenX = SystemParameters.PrimaryScreenWidth / 96 * dpiX;
double screenY = SystemParameters.PrimaryScreenHeight / 96 * dpiY;
person Marco Concas    schedule 24.07.2019

попробуйте это .. я считаю, что это может исправить ошибку .....

Система.Windows.Form1.Screen.PrimaryScreen.Bounds.Height; Система.Windows.Form1.Screen.PrimaryScreen.Bounds.Widtht;

person deepu    schedule 15.03.2010