Изменен принятый ответ, чтобы отразить лучший способ сделать это из WPF. System.Windows.SystemParameters. *
chilltemp
1
Одержимость отказом от пространства имен WinForms кажется мне странной, это ничего вам не дает; вместо этого он оставляет вас без инструментов, необходимых для правильного решения проблемы.
Джефф Йейтс,
4
Для меня это не WinForms vs. WPF. Речь идет об изучении чего-то нового. Я не могу решить, какой путь лучше, если не научусь обоим.
chilltemp 03
3
Что ж, в этом сценарии нет «обоих способов», поскольку есть только один способ сделать это - использовать материал WinForms.
Джефф Йейтс,
@ Джефф Йейтс: Вы правы. Я откопал исходный проект, для которого задал этот вопрос, и обнаружил, что использовал свойства PrimaryScreen *. Они решили мои сегодняшние потребности, но не вопрос, который я задал. Извините за беготню; Я соответственно изменил принятый ответ.
chilltemp
Ответы:
145
Screen.FromControl, Screen.FromPointи Screen.FromRectangleдолжен помочь вам в этом. Например, в WinForms это будет:
classMyForm : Form
{
public Rectangle GetScreen()
{
return Screen.FromControl(this).Bounds;
}
}
Я не знаю аналогичного вызова для WPF. Следовательно, вам нужно сделать что-то вроде этого метода расширения.
Возможно, моя пометка не прояснила, что я использую окна WPF, а не WinForms. У меня нет ссылки на System.Windows.Forms.dll, и она все равно не будет работать, поскольку WPF имеет собственное дерево наследования.
chilltemp
1
Пожалуйста. Приношу свои извинения за то, что не получил прямого ответа - мне пришлось изучить, что было доступно в WPF, прежде чем я обновил свой пост.
Джефф Йейтс
Это позволяет разместить окно с правой стороны: var bounds = this.GetScreen (). WorkingArea; this.Left = bounds.Right - this.Width; Но для этого требуются ссылки на System.Windows.Forms и System.Drawing, что не идеально.
Энтони,
1
@devios Помните, что этот вызов не поддерживает DPI; вам нужно будет произвести расчеты.
Lynn Crumbling
6
В моем приложении VS 2015 WPF, нацеленном на .NET 4.5 в моей системе с 4 мониторами в Windows 10 Pro (v10.0.14393), windowна мониторе над моим основным (например, его Top < 0), FromHandleвернул Screenдля моего основного монитора (хотя windowбыл полностью в пределах Вторичный монитор)!?! Вздох. Похоже, мне придется самому искать в Screen.AllScreensмассиве. Почему вещи не могут "просто работать"?!? Arrrrgh.
Tom
63
Вы можете использовать это, чтобы получить границы рабочего пространства рабочего стола основного экрана:
Я запуталась ... Вроде только возвращает размеры основного экрана. Я хочу знать размеры экрана, на котором сейчас находится окно ...
VitalyB
1
это не отвечает на вопрос, и даже если вы просто хотите получить размер основного дисплея, параметры SystemParameters (в WPF) неверны. они возвращают независимые от устройства единицы, а не пиксели. для лучшей реализации см. этот ответ: stackoverflow.com/questions/254197/…
Патрик Клуг
1
PrimaryScreenHeight / Width работали точно так, как ожидалось, и в MSDN указано следующее: «Получает значение, указывающее высоту экрана в пикселях основного монитора». WorkArea конкретно не говорит о пикселях, но документация и примеры использования заставляют меня поверить, что это тоже пиксели. У вас есть ссылка на что-то, указывающее на использование устройств, независимых от устройств?
А затем получите дескриптор монитора и информацию о мониторе, подобную этой.
var hwnd = new WindowInteropHelper( this ).EnsureHandle();
var monitor = NativeMethods.MonitorFromWindow( hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST );
if ( monitor != IntPtr.Zero )
{
var monitorInfo = new NativeMonitorInfo();
NativeMethods.GetMonitorInfo( monitor, monitorInfo );
var left = monitorInfo.Monitor.Left;
var top = monitorInfo.Monitor.Top;
var width = ( monitorInfo.Monitor.Right - monitorInfo.Monitor.Left );
var height = ( monitorInfo.Monitor.Bottom - monitorInfo.Monitor.Top );
}
Это для основного экрана - что, если окно вашего приложения находится на виртуальном (расширенном) экране (т. Е. К вашему ПК подключены один или два внешних монитора)?
Мэтт
4
Я хотел получить разрешение экрана перед открытием первого из моих окон, поэтому вот быстрое решение для открытия невидимого окна перед фактическим измерением размеров экрана (вам необходимо адаптировать параметры окна к вашему окну, чтобы гарантировать, что оба открыты тот же экран - WindowStartupLocationглавное главное)
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
Dim BarWidth As Double = SystemParameters.VirtualScreenWidth - SystemParameters.WorkArea.Width
Dim BarHeight As Double = SystemParameters.VirtualScreenHeight - SystemParameters.WorkArea.Height
Me.Left = (SystemParameters.VirtualScreenWidth - Me.ActualWidth - BarWidth) / 2
Me.Top = (SystemParameters.VirtualScreenHeight - Me.ActualHeight - BarHeight) / 2
End Sub
Главный вопрос - положение экрана. Подобно установщику Msi, Innosetup или другим, я создал свой собственный установщик с проверкой ЦП, проверкой разрешений, проверкой драйверов и многим другим, очень простым в использовании. Вот скриншот примерно.
Nasenbaer 07
3
Мне нужно было установить максимальный размер оконного приложения. Это можно изменить в зависимости от того, отображается ли приложение на главном или дополнительном экране. Чтобы решить эту проблему, мы создали простой метод, который я покажу вам ниже:
///<summary>/// Set the max size of the application window taking into account the current monitor///</summary>publicstaticvoidSetMaxSizeWindow(ioConnect _receiver)
{
Point absoluteScreenPos = _receiver.PointToScreen(Mouse.GetPosition(_receiver));
if (System.Windows.SystemParameters.VirtualScreenLeft == System.Windows.SystemParameters.WorkArea.Left)
{
//Primary Monitor is on the Leftif (absoluteScreenPos.X <= System.Windows.SystemParameters.PrimaryScreenWidth)
{
//Primary monitor
_receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.WorkArea.Width;
_receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.WorkArea.Height;
}
else
{
//Secondary monitor
_receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.VirtualScreenWidth - System.Windows.SystemParameters.WorkArea.Width;
_receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.VirtualScreenHeight;
}
}
if (System.Windows.SystemParameters.VirtualScreenLeft < 0)
{
//Primary Monitor is on the Rightif (absoluteScreenPos.X > 0)
{
//Primary monitor
_receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.WorkArea.Width;
_receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.WorkArea.Height;
}
else
{
//Secondary monitor
_receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.VirtualScreenWidth - System.Windows.SystemParameters.WorkArea.Width;
_receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.VirtualScreenHeight;
}
}
}
в C # winforms у меня есть начальная точка (на случай, когда у нас несколько мониторов / диплей и одна форма вызывает другую) с помощью следующего метода:
private Point get_start_point()
{
returnnew Point(Screen.GetBounds(parent_class_with_form.ActiveForm).X,
Screen.GetBounds(parent_class_with_form.ActiveForm).Y
);
}
Ответы:
Screen.FromControl
,Screen.FromPoint
иScreen.FromRectangle
должен помочь вам в этом. Например, в WinForms это будет:class MyForm : Form { public Rectangle GetScreen() { return Screen.FromControl(this).Bounds; } }
Я не знаю аналогичного вызова для WPF. Следовательно, вам нужно сделать что-то вроде этого метода расширения.
static class ExtensionsForWPF { public static System.Windows.Forms.Screen GetScreen(this Window window) { return System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(window).Handle); } }
источник
window
на мониторе над моим основным (например, егоTop < 0
),FromHandle
вернулScreen
для моего основного монитора (хотяwindow
был полностью в пределах Вторичный монитор)!?! Вздох. Похоже, мне придется самому искать вScreen.AllScreens
массиве. Почему вещи не могут "просто работать"?!? Arrrrgh.Вы можете использовать это, чтобы получить границы рабочего пространства рабочего стола основного экрана:
System.Windows.SystemParameters.WorkArea
Это также полезно для получения только размера основного экрана:
System.Windows.SystemParameters.PrimaryScreenWidth
System.Windows.SystemParameters.PrimaryScreenHeight
источник
Также вам могут понадобиться:
чтобы получить общий размер всех мониторов, а не одного в частности.
источник
PresentationFramework.dll
иusing System.Windows;
Добавление решения, которое использует не WinForms, а NativeMethods. Сначала вам нужно определить необходимые нативные методы.
public static class NativeMethods { public const Int32 MONITOR_DEFAULTTOPRIMERTY = 0x00000001; public const Int32 MONITOR_DEFAULTTONEAREST = 0x00000002; [DllImport( "user32.dll" )] public static extern IntPtr MonitorFromWindow( IntPtr handle, Int32 flags ); [DllImport( "user32.dll" )] public static extern Boolean GetMonitorInfo( IntPtr hMonitor, NativeMonitorInfo lpmi ); [Serializable, StructLayout( LayoutKind.Sequential )] public struct NativeRectangle { public Int32 Left; public Int32 Top; public Int32 Right; public Int32 Bottom; public NativeRectangle( Int32 left, Int32 top, Int32 right, Int32 bottom ) { this.Left = left; this.Top = top; this.Right = right; this.Bottom = bottom; } } [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Auto )] public sealed class NativeMonitorInfo { public Int32 Size = Marshal.SizeOf( typeof( NativeMonitorInfo ) ); public NativeRectangle Monitor; public NativeRectangle Work; public Int32 Flags; } }
А затем получите дескриптор монитора и информацию о мониторе, подобную этой.
var hwnd = new WindowInteropHelper( this ).EnsureHandle(); var monitor = NativeMethods.MonitorFromWindow( hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST ); if ( monitor != IntPtr.Zero ) { var monitorInfo = new NativeMonitorInfo(); NativeMethods.GetMonitorInfo( monitor, monitorInfo ); var left = monitorInfo.Monitor.Left; var top = monitorInfo.Monitor.Top; var width = ( monitorInfo.Monitor.Right - monitorInfo.Monitor.Left ); var height = ( monitorInfo.Monitor.Bottom - monitorInfo.Monitor.Top ); }
источник
Добавить в ffpf
Screen.FromControl(this).Bounds
источник
Остерегайтесь масштабного коэффициента ваших окон (100% / 125% / 150% / 200%). Вы можете получить реальный размер экрана, используя следующий код:
источник
Я хотел получить разрешение экрана перед открытием первого из моих окон, поэтому вот быстрое решение для открытия невидимого окна перед фактическим измерением размеров экрана (вам необходимо адаптировать параметры окна к вашему окну, чтобы гарантировать, что оба открыты тот же экран -
WindowStartupLocation
главное главное)Window w = new Window(); w.ResizeMode = ResizeMode.NoResize; w.WindowState = WindowState.Normal; w.WindowStyle = WindowStyle.None; w.Background = Brushes.Transparent; w.Width = 0; w.Height = 0; w.AllowsTransparency = true; w.IsHitTestVisible = false; w.WindowStartupLocation = WindowStartupLocation.Manual; w.Show(); Screen scr = Screen.FromHandle(new WindowInteropHelper(w).Handle); w.Close();
источник
Это « решение Center Screen DotNet 4.5 », использующее SystemParameters вместо System.Windows.Forms или My.Compuer.Screen : с тех пор, как Windows 8 изменилась расчет размеров экрана, единственный способ, которым это работает для меня, выглядит так (расчет панели задач включены):
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded Dim BarWidth As Double = SystemParameters.VirtualScreenWidth - SystemParameters.WorkArea.Width Dim BarHeight As Double = SystemParameters.VirtualScreenHeight - SystemParameters.WorkArea.Height Me.Left = (SystemParameters.VirtualScreenWidth - Me.ActualWidth - BarWidth) / 2 Me.Top = (SystemParameters.VirtualScreenHeight - Me.ActualHeight - BarHeight) / 2 End Sub
источник
Мне нужно было установить максимальный размер оконного приложения. Это можно изменить в зависимости от того, отображается ли приложение на главном или дополнительном экране. Чтобы решить эту проблему, мы создали простой метод, который я покажу вам ниже:
/// <summary> /// Set the max size of the application window taking into account the current monitor /// </summary> public static void SetMaxSizeWindow(ioConnect _receiver) { Point absoluteScreenPos = _receiver.PointToScreen(Mouse.GetPosition(_receiver)); if (System.Windows.SystemParameters.VirtualScreenLeft == System.Windows.SystemParameters.WorkArea.Left) { //Primary Monitor is on the Left if (absoluteScreenPos.X <= System.Windows.SystemParameters.PrimaryScreenWidth) { //Primary monitor _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.WorkArea.Width; _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.WorkArea.Height; } else { //Secondary monitor _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.VirtualScreenWidth - System.Windows.SystemParameters.WorkArea.Width; _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.VirtualScreenHeight; } } if (System.Windows.SystemParameters.VirtualScreenLeft < 0) { //Primary Monitor is on the Right if (absoluteScreenPos.X > 0) { //Primary monitor _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.WorkArea.Width; _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.WorkArea.Height; } else { //Secondary monitor _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.VirtualScreenWidth - System.Windows.SystemParameters.WorkArea.Width; _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.VirtualScreenHeight; } } }
источник
в C # winforms у меня есть начальная точка (на случай, когда у нас несколько мониторов / диплей и одна форма вызывает другую) с помощью следующего метода:
private Point get_start_point() { return new Point(Screen.GetBounds(parent_class_with_form.ActiveForm).X, Screen.GetBounds(parent_class_with_form.ActiveForm).Y ); }
источник
WinForms
Для настроек с несколькими мониторами вам также необходимо учитывать положение X и Y:
Rectangle activeScreenDimensions = Screen.FromControl(this).Bounds; this.Size = new Size(activeScreenDimensions.Width + activeScreenDimensions.X, activeScreenDimensions.Height + activeScreenDimensions.Y);
источник
Эта отладка код должен хорошо справиться с задачей:
Вы можете изучить свойства класса экрана
Поместите все дисплеи в массив или список с помощью Screen.AllScreens, затем захватите индекс текущего дисплея и его свойства.
C # (преобразовано из VB компанией Telerik - проверьте еще раз)
{ List<Screen> arrAvailableDisplays = new List<Screen>(); List<string> arrDisplayNames = new List<string>(); foreach (Screen Display in Screen.AllScreens) { arrAvailableDisplays.Add(Display); arrDisplayNames.Add(Display.DeviceName); } Screen scrCurrentDisplayInfo = Screen.FromControl(this); string strDeviceName = Screen.FromControl(this).DeviceName; int idxDevice = arrDisplayNames.IndexOf(strDeviceName); MessageBox.Show(this, "Number of Displays Found: " + arrAvailableDisplays.Count.ToString() + Constants.vbCrLf + "ID: " + idxDevice.ToString() + Constants.vbCrLf + "Device Name: " + scrCurrentDisplayInfo.DeviceName.ToString + Constants.vbCrLf + "Primary: " + scrCurrentDisplayInfo.Primary.ToString + Constants.vbCrLf + "Bounds: " + scrCurrentDisplayInfo.Bounds.ToString + Constants.vbCrLf + "Working Area: " + scrCurrentDisplayInfo.WorkingArea.ToString + Constants.vbCrLf + "Bits per Pixel: " + scrCurrentDisplayInfo.BitsPerPixel.ToString + Constants.vbCrLf + "Width: " + scrCurrentDisplayInfo.Bounds.Width.ToString + Constants.vbCrLf + "Height: " + scrCurrentDisplayInfo.Bounds.Height.ToString + Constants.vbCrLf + "Work Area Width: " + scrCurrentDisplayInfo.WorkingArea.Width.ToString + Constants.vbCrLf + "Work Area Height: " + scrCurrentDisplayInfo.WorkingArea.Height.ToString, "Current Info for Display '" + scrCurrentDisplayInfo.DeviceName.ToString + "' - ID: " + idxDevice.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Information); }
VB (Исходный код)
Dim arrAvailableDisplays As New List(Of Screen)() Dim arrDisplayNames As New List(Of String)() For Each Display As Screen In Screen.AllScreens arrAvailableDisplays.Add(Display) arrDisplayNames.Add(Display.DeviceName) Next Dim scrCurrentDisplayInfo As Screen = Screen.FromControl(Me) Dim strDeviceName As String = Screen.FromControl(Me).DeviceName Dim idxDevice As Integer = arrDisplayNames.IndexOf(strDeviceName) MessageBox.Show(Me, "Number of Displays Found: " + arrAvailableDisplays.Count.ToString & vbCrLf & "ID: " & idxDevice.ToString + vbCrLf & "Device Name: " & scrCurrentDisplayInfo.DeviceName.ToString + vbCrLf & "Primary: " & scrCurrentDisplayInfo.Primary.ToString + vbCrLf & "Bounds: " & scrCurrentDisplayInfo.Bounds.ToString + vbCrLf & "Working Area: " & scrCurrentDisplayInfo.WorkingArea.ToString + vbCrLf & "Bits per Pixel: " & scrCurrentDisplayInfo.BitsPerPixel.ToString + vbCrLf & "Width: " & scrCurrentDisplayInfo.Bounds.Width.ToString + vbCrLf & "Height: " & scrCurrentDisplayInfo.Bounds.Height.ToString + vbCrLf & "Work Area Width: " & scrCurrentDisplayInfo.WorkingArea.Width.ToString + vbCrLf & "Work Area Height: " & scrCurrentDisplayInfo.WorkingArea.Height.ToString, "Current Info for Display '" & scrCurrentDisplayInfo.DeviceName.ToString & "' - ID: " & idxDevice.ToString, MessageBoxButtons.OK, MessageBoxIcon.Information)
источник