Що я шукаю - це еквівалент System.Windows.SystemParameters.WorkArea
монітора, на якому зараз знаходиться вікно.
Пояснення: Розглянуте вікно - WPF
ні WinForm
.
Що я шукаю - це еквівалент System.Windows.SystemParameters.WorkArea
монітора, на якому зараз знаходиться вікно.
Пояснення: Розглянуте вікно - WPF
ні WinForm
.
Відповіді:
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%). Ви можете отримати реальний розмір екрана, скориставшись наступним кодом:
SystemParameters.FullPrimaryScreenHeight
SystemParameters.FullPrimaryScreenWidth
Я хотів мати роздільну здатність екрана перед відкриттям першого вікна, тому тут швидке рішення відкрити невидиме вікно перед тим, як фактично виміряти розміри екрана (вам потрібно адаптувати параметри вікна до вашого вікна, щоб переконатися, що обидва відкриваються той же екран - головне 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();
Це "Центр екрану 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
);
}
Для налаштування декількох моніторів вам також знадобиться обліковий запис для позицій 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)