Я знаю, что могу получить размер основного экрана, используя
System.Windows.SystemParameters.PrimaryScreenWidth;
System.Windows.SystemParameters.PrimaryScreenHeight;
Но как мне узнать размер текущего экрана? (Пользователи многоэкранного режима не всегда используют основной экран, и не все экраны имеют одинаковое разрешение, верно?)
Было бы неплохо получить доступ к размеру из XAML, но этого будет достаточно из кода (C #).
Ответы:
Насколько мне известно, встроенной функции WPF для получения размеров текущего монитора нет. Вместо этого вы можете PInvoke встроить функции нескольких мониторов , обернуть их в управляемый класс и предоставить все свойства, необходимые для их использования из XAML.
источник
Я создал небольшую оболочку вокруг экрана из System.Windows.Forms, в настоящее время все работает ... Не уверен, что насчет "аппаратно-независимых пикселей".
public class WpfScreen { public static IEnumerable<WpfScreen> AllScreens() { foreach (Screen screen in System.Windows.Forms.Screen.AllScreens) { yield return new WpfScreen(screen); } } public static WpfScreen GetScreenFrom(Window window) { WindowInteropHelper windowInteropHelper = new WindowInteropHelper(window); Screen screen = System.Windows.Forms.Screen.FromHandle(windowInteropHelper.Handle); WpfScreen wpfScreen = new WpfScreen(screen); return wpfScreen; } public static WpfScreen GetScreenFrom(Point point) { int x = (int) Math.Round(point.X); int y = (int) Math.Round(point.Y); // are x,y device-independent-pixels ?? System.Drawing.Point drawingPoint = new System.Drawing.Point(x, y); Screen screen = System.Windows.Forms.Screen.FromPoint(drawingPoint); WpfScreen wpfScreen = new WpfScreen(screen); return wpfScreen; } public static WpfScreen Primary { get { return new WpfScreen(System.Windows.Forms.Screen.PrimaryScreen); } } private readonly Screen screen; internal WpfScreen(System.Windows.Forms.Screen screen) { this.screen = screen; } public Rect DeviceBounds { get { return this.GetRect(this.screen.Bounds); } } public Rect WorkingArea { get { return this.GetRect(this.screen.WorkingArea); } } private Rect GetRect(Rectangle value) { // should x, y, width, height be device-independent-pixels ?? return new Rect { X = value.X, Y = value.Y, Width = value.Width, Height = value.Height }; } public bool IsPrimary { get { return this.screen.Primary; } } public string DeviceName { get { return this.screen.DeviceName; } } }
источник
Вот приятель. Это даст вам только ширину и высоту рабочей области.
System.Windows.SystemParameters.WorkArea.Width System.Windows.SystemParameters.WorkArea.Height
источник
Это даст вам текущий экран, основанный на левом верхнем углу окна, просто вызовите this.CurrentScreen (), чтобы получить информацию о текущем экране.
using System.Windows; using System.Windows.Forms; namespace Common.Helpers { public static class WindowHelpers { public static Screen CurrentScreen(this Window window) { return Screen.FromPoint(new System.Drawing.Point((int)window.Left,(int)window.Top)); } } }
источник
Найдите время, чтобы просмотреть элементы SystemParameters.
VirtualScreenWidth
VirtualScreenHeight
Они даже учитывают взаимное расположение экранов.
Проверено только с двумя мониторами.
источник
Почему бы просто не использовать это?
var interopHelper = new WindowInteropHelper(System.Windows.Application.Current.MainWindow); var activeScreen = Screen.FromHandle(interopHelper.Handle);
источник
System.Windows.Forms.Screen
чтобы справиться с независимым от устройства пикселемЕсли вы знакомы с использованием класса System.Windows.Forms, вы можете просто добавить ссылку на класс System.Windows.Forms в свой проект:
Обозреватель решений -> Ссылки -> Добавить ссылки ... -> (Сборки: Framework) -> прокрутите вниз и проверьте сборку System.Windows.Forms -> ОК .
Теперь вы можете добавить using System.Windows.Forms; оператор и используйте screen в своем проекте wpf, как и раньше.
источник
Мне также понадобился текущий размер экрана, в частности, рабочая область, которая вернула прямоугольник, исключая ширину панели задач.
Я использовал его для изменения положения окна, которое открывается вправо и вниз, туда, где расположена мышь. Поскольку окно довольно большое, во многих случаях оно выходило за пределы экрана. Следующий код основан на @ej ответ: Это даст вам текущий экран ... . Разница в том, что я также показываю свой алгоритм изменения положения, в котором, как я полагаю, и есть суть.
Код:
using System.Windows; using System.Windows.Forms; namespace MySample { public class WindowPostion { /// <summary> /// This method adjust the window position to avoid from it going /// out of screen bounds. /// </summary> /// <param name="topLeft">The requiered possition without its offset</param> /// <param name="maxSize">The max possible size of the window</param> /// <param name="offset">The offset of the topLeft postion</param> /// <param name="margin">The margin from the screen</param> /// <returns>The adjusted position of the window</returns> System.Drawing.Point Adjust(System.Drawing.Point topLeft, System.Drawing.Point maxSize, int offset, int margin) { Screen currentScreen = Screen.FromPoint(topLeft); System.Drawing.Rectangle rect = currentScreen.WorkingArea; // Set an offset from mouse position. topLeft.Offset(offset, offset); // Check if the window needs to go above the task bar, // when the task bar shadows the HUD window. int totalHight = topLeft.Y + maxSize.Y + margin; if (totalHight > rect.Bottom) { topLeft.Y -= (totalHight - rect.Bottom); // If the screen dimensions exceed the hight of the window // set it just bellow the top bound. if (topLeft.Y < rect.Top) { topLeft.Y = rect.Top + margin; } } int totalWidth = topLeft.X + maxSize.X + margin; // Check if the window needs to move to the left of the mouse, // when the HUD exceeds the right window bounds. if (totalWidth > rect.Right) { // Since we already set an offset remove it and add the offset // to the other side of the mouse (2x) in addition include the // margin. topLeft.X -= (maxSize.X + (2 * offset + margin)); // If the screen dimensions exceed the width of the window // don't exceed the left bound. if (topLeft.X < rect.Left) { topLeft.X = rect.Left + margin; } } return topLeft; } } }
Некоторые пояснения:
1) topLeft - position of the top left at the desktop (works for multi screens - with different aspect ratio). Screen1 Screen2 ─ ┌───────────────────┐┌───────────────────┐ Screen3 ▲ │ ││ │┌─────────────────┐ ─ │ │ ││ ││ ▼- │ ▲ 1080 │ │ ││ ││ │ │ │ │ ││ ││ │ │ 900 ▼ │ ││ ││ │ ▼ ─ └──────┬─────┬──────┘└──────┬─────┬──────┘└──────┬────┬─────┘ ─ ─┴─────┴─ ─┴─────┴─ ─┴────┴─ │◄─────────────────►││◄─────────────────►││◄───────────────►│ 1920 1920 1440 If the mouse is in Screen3 a possible value might be: topLeft.X=4140 topLeft.Y=195 2) offset - the offset from the top left, one value for both X and Y directions. 3) maxSize - the maximal size of the window - including its size when it is expanded - from the following example we need maxSize.X = 200, maxSize.Y = 150 - To avoid the expansion being out of bound. Non expanded window: ┌──────────────────────────────┐ ─ │ Window Name [X]│ ▲ ├──────────────────────────────┤ │ │ ┌─────────────────┐ │ │ 100 │ Text1: │ │ │ │ │ └─────────────────┘ │ │ │ [▼] │ ▼ └──────────────────────────────┘ ─ │◄────────────────────────────►│ 200 Expanded window: ┌──────────────────────────────┐ ─ │ Window Name [X]│ ▲ ├──────────────────────────────┤ │ │ ┌─────────────────┐ │ │ │ Text1: │ │ │ │ │ └─────────────────┘ │ │ 150 │ [▲] │ │ │ ┌─────────────────┐ │ │ │ Text2: │ │ │ │ │ └─────────────────┘ │ ▼ └──────────────────────────────┘ ─ │◄────────────────────────────►│ 200 4) margin - The distance the window should be from the screen work-area - Example: ┌─────────────────────────────────────────────────────────────┐ ─ │ │ ↕ Margin │ │ ─ │ │ │ │ │ │ │ ┌──────────────────────────────┐ │ │ │ Window Name [X]│ │ │ ├──────────────────────────────┤ │ │ │ ┌─────────────────┐ │ │ │ │ Text1: │ │ │ │ │ │ └─────────────────┘ │ │ │ │ [▲] │ │ │ │ ┌─────────────────┐ │ │ │ │ Text2: │ │ │ │ │ │ └─────────────────┘ │ │ │ └──────────────────────────────┘ │ ─ │ │ ↕ Margin ├──────────────────────────────────────────────────┬──────────┤ ─ │[start] [♠][♦][♣][♥] │en│ 12:00 │ └──────────────────────────────────────────────────┴──────────┘ │◄─►│ │◄─►│ Margin Margin * Note that this simple algorithm will always want to leave the cursor out of the window, therefor the window will jumps to its left: ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ │ ▼-┌──────────────┐ │ ┌──────────────┐▼- │ │ │ Window [X]│ │ │ Window [X]│ │ │ ├──────────────┤ │ ├──────────────┤ │ │ │ ┌───┐ │ │ │ ┌───┐ │ │ │ │ Val: │ │ │ -> │ │ Val: │ │ │ │ │ │ └───┘ │ │ │ └───┘ │ │ │ └──────────────┘ │ └──────────────┘ │ │ │ │ │ ├──────────────────────┬──────────┤ ├──────────────────────┬──────────┤ │[start] [♠][♦][♣] │en│ 12:00 │ │[start] [♠][♦][♣] │en│ 12:00 │ └──────────────────────┴──────────┘ └──────────────────────┴──────────┘ If this is not a requirement, you can add a parameter to just use the margin: ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ │ ▼-┌──────────────┐ │ ┌─▼-───────────┐ │ │ │ Window [X]│ │ │ Window [X]│ │ │ ├──────────────┤ │ ├──────────────┤ │ │ │ ┌───┐ │ │ │ ┌───┐ │ │ │ │ Val: │ │ │ -> │ │ Val: │ │ │ │ │ │ └───┘ │ │ │ └───┘ │ │ │ └──────────────┘ │ └──────────────┘ │ │ │ │ │ ├──────────────────────┬──────────┤ ├──────────────────────┬──────────┤ │[start] [♠][♦][♣] │en│ 12:00 │ │[start] [♠][♦][♣] │en│ 12:00 │ └──────────────────────┴──────────┘ └──────────────────────┴──────────┘ * Supports also the following scenarios: 1) Screen over screen: ┌─────────────────┐ │ │ │ │ │ │ │ │ └─────────────────┘ ┌───────────────────┐ │ │ │ ▼- │ │ │ │ │ │ │ └──────┬─────┬──────┘ ─┴─────┴─ 2) Window bigger than screen hight or width ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ │ │ │ ┌──────────────┐ │ │ │ │ │ Window [X]│ │ │ ▼-┌────────────│─┐ │ ├──────────────┤ ▼- │ │ │ Window [│]│ │ │ ┌───┐ │ │ │ ├────────────│─┤ -> │ │ Val: │ │ │ │ │ │ ┌───┐│ │ │ │ └───┘ │ │ │ │ Val: │ ││ │ │ │ ┌───┐ │ │ │ │ └───┘│ │ │ │ Val: │ │ │ │ ├──────────────────────┬──────────┤ │ ├──────────────────────┬──────────┤ │[start] [♠][♦][♣] │en│ 12:00 │ │ │[start] [♠][♦][♣] │en│ 12:00 │ └──────────────────────┴──────────┘ │ └──────────────────────┴──────────┘ │ ┌───┐ │ │ └───┘ │ │ Val: │ │ │ └──────────────┘ │ └───┘ │ └──────────────┘ ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ │ │ │ │ │ │ │ ┌───────────────────────────────│───┐ │ ▼-┌──────────────────────────│────────┐ │ │ W▼-dow │[X]│ │ │ Window │ [X]│ │ ├───────────────────────────────│───┤ │ ├──────────────────────────│────────┤ │ │ ┌───┐ ┌───┐ ┌─┤─┐ │ │ │ ┌───┐ ┌───┐ │ ┌───┐ │ -> │ │ Val: │ │ Val: │ │ Val: │ │ │ │ │ │ Val: │ │ Val: │ │ Va│: │ │ │ │ │ └───┘ └───┘ └─┤─┘ │ │ │ └───┘ └───┘ │ └───┘ │ │ └───────────────────────────────│───┘ ├──────────────────────┬──────────┤────────┘ ├──────────────────────┬──────────┤ │[start] [♠][♦][♣] │en│ 12:00 │ │[start] [♠][♦][♣] │en│ 12:00 │ └──────────────────────┴──────────┘ └──────────────────────┴──────────┘
<remark><code>...</code></remark>
источник
Я понимаю требования. Дело в том, что существуют методы WPF для получения этих значений, но да, один из участников прав, а не напрямую. Решение состоит не в том, чтобы найти все эти обходные пути, а в изменении первоначального подхода в соответствии с чистым дизайном и разработкой.
A) Установите начальное главное окно на экран
Б) Получите значения для ActualWindow, включая массу полезных методов WPF
C) Вы можете добавить столько окон, сколько захотите, для желаемого поведения, например, изменение размера, сворачивание чего угодно ... но теперь вы всегда можете получить доступ к загруженному и визуализированному экрану
Будьте осторожны со следующим примером, есть некоторый код, который заставляет использовать такой подход, однако он должен работать (он даст вам баллы для каждого из углов экрана): Рабочий пример для одиночного, Двойной монитор и разные разрешения (в классе основного главного окна):
InitializeComponent(); […] ActualWindow.AddHandler(Window.LoadedEvent, new RoutedEventHandler(StartUpScreenLoaded));
Маршрутизированное событие:
private void StartUpScreenLoaded(object sender, RoutedEventArgs e) { Window StartUpScreen = sender as Window; // Dispatcher Format B: Dispatcher.Invoke(new Action(() => { // Get Actual Window on Loaded StartUpScreen.InvalidateVisual(); System.Windows.Point CoordinatesTopRight = StartUpScreen.TranslatePoint(new System.Windows.Point((StartUpScreen.ActualWidth), (0d)), ActualWindow); System.Windows.Point CoordinatesBottomRight = StartUpScreen.TranslatePoint(new System.Windows.Point((StartUpScreen.ActualWidth), (StartUpScreen.ActualHeight)), ActualWindow); System.Windows.Point CoordinatesBottomLeft = StartUpScreen.TranslatePoint(new System.Windows.Point((0d), (StartUpScreen.ActualHeight)), ActualWindow); // Set the Canvas Top Right, Bottom Right, Bottom Left Coordinates System.Windows.Application.Current.Resources["StartUpScreenPointTopRight"] = CoordinatesTopRight; System.Windows.Application.Current.Resources["StartUpScreenPointBottomRight"] = CoordinatesBottomRight; System.Windows.Application.Current.Resources["StartUpScreenPointBottomLeft"] = CoordinatesBottomLeft; }), DispatcherPriority.Loaded); }
источник
Если вы используете любое полноэкранное окно (имеющее его
WindowState = WindowState.Maximized, WindowStyle = WindowStyle.None
), вы можете обернуть его содержимоеSystem.Windows.Controls.Canvas
следующим образом:<Canvas Name="MyCanvas" Width="auto" Height="auto"> ... </Canvas>
Затем вы можете использовать
MyCanvas.ActualWidth
и,MyCanvas.ActualHeight
чтобы получить разрешение текущего экрана с учетом настроек DPI и в единицах измерения, независимых от устройства. Он не добавляет полей, как это делает само развернутое окно.(Canvas принимает
UIElement
s как дочерние элементы, поэтому вы сможете использовать его с любым контентом.)источник
WindowStartupLocation="CenterOwner"
Отцентрируйте окно на экране в XAML, затем вызовите WindowLoaded ()double ScreenHeight = 2 * (Top + 0.5 * Height);
источник
double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth; double screenhight= System.Windows.SystemParameters.PrimaryScreenHeight;
источник
Работает с
this.Width = System.Windows.SystemParameters.VirtualScreenWidth; this.Height = System.Windows.SystemParameters.VirtualScreenHeight;
Проверено на 2-х мониторах.
источник
VirtualScreen
охватывает все экраны - так что это никогда не сработает, если у вас более одного экрана!