Was ich suche, entspricht System.Windows.SystemParameters.WorkArea
dem Monitor, auf dem sich das Fenster gerade befindet.
Klarstellung: Das fragliche Fenster ist WPF
nicht WinForm
.
Was ich suche, entspricht System.Windows.SystemParameters.WorkArea
dem Monitor, auf dem sich das Fenster gerade befindet.
Klarstellung: Das fragliche Fenster ist WPF
nicht WinForm
.
Antworten:
Screen.FromControl
, Screen.FromPoint
Und Screen.FromRectangle
Sie sollten dabei helfen. Zum Beispiel in WinForms wäre es:
class MyForm : Form
{
public Rectangle GetScreen()
{
return Screen.FromControl(this).Bounds;
}
}
Ich kenne keinen entsprechenden Anruf für WPF. Daher müssen Sie so etwas wie diese Erweiterungsmethode ausführen.
static class ExtensionsForWPF
{
public static System.Windows.Forms.Screen GetScreen(this Window window)
{
return System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(window).Handle);
}
}
window
auf dem Monitor über meiner Primary ist ( zum Beispiel seines Top < 0
), FromHandle
kehrte das Screen
allerdings für meinen primärer Monitor (selbst window
war vollständig innerhalb der sekundäre Monitor)!?! Seufzer. Es sieht so aus, als Screen.AllScreens
müsste ich das Array selbst durchsuchen . Warum können Dinge nicht "einfach funktionieren"?!? Arrrrgh.
Sie können dies verwenden, um Desktop-Arbeitsbereichsgrenzen des primären Bildschirms abzurufen:
System.Windows.SystemParameters.WorkArea
Dies ist auch nützlich, um nur die Größe des primären Bildschirms zu ermitteln:
System.Windows.SystemParameters.PrimaryScreenWidth
System.Windows.SystemParameters.PrimaryScreenHeight
Möglicherweise benötigen Sie auch:
um die kombinierte Größe aller Monitore und nicht eines bestimmten zu erhalten.
PresentationFramework.dll
undusing System.Windows;
Hinzufügen einer Lösung, die stattdessen nicht WinForms, sondern NativeMethods verwendet. Zuerst müssen Sie die erforderlichen nativen Methoden definieren.
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;
}
}
Und dann holen Sie sich den Monitorgriff und die Monitorinformationen wie folgt.
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 );
}
Add zu ffpf
Screen.FromControl(this).Bounds
Achten Sie auf den Skalierungsfaktor Ihrer Fenster (100% / 125% / 150% / 200%). Sie können die tatsächliche Bildschirmgröße mithilfe des folgenden Codes ermitteln:
SystemParameters.FullPrimaryScreenHeight
SystemParameters.FullPrimaryScreenWidth
Ich wollte die Bildschirmauflösung vor dem Öffnen des ersten meiner Fenster haben, daher hier eine schnelle Lösung, um ein unsichtbares Fenster zu öffnen, bevor die Bildschirmabmessungen tatsächlich gemessen werden (Sie müssen die Fensterparameter an Ihr Fenster anpassen, um sicherzustellen, dass beide geöffnet sind der gleiche Bildschirm - hauptsächlich WindowStartupLocation
ist das wichtig)
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();
Dies ist eine "Center Screen DotNet 4.5-Lösung ", die SystemParameters anstelle von System.Windows.Forms oder My.Compuer.Screen verwendet : Da Windows 8 die Berechnung der Bildschirmabmessungen geändert hat, sieht es für mich nur so aus (Taskleistenberechnung) inbegriffen):
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
Ich musste die maximale Größe meiner Fensteranwendung festlegen. Dieser könnte entsprechend geändert werden. Die Anwendung wird im primären Bildschirm oder im sekundären angezeigt. Um dieses Problem zu lösen, haben wir eine einfache Methode erstellt, die ich Ihnen als Nächstes zeige:
/// <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;
}
}
}
In C # -Winforms habe ich einen Startpunkt (für den Fall, dass wir mehrere Monitore / Diplomaten haben und ein Formular einen anderen aufruft) mit Hilfe der folgenden Methode:
private Point get_start_point()
{
return
new Point(Screen.GetBounds(parent_class_with_form.ActiveForm).X,
Screen.GetBounds(parent_class_with_form.ActiveForm).Y
);
}
Für Multi-Monitor-Setups benötigen Sie außerdem ein Konto für die X- und Y-Position:
Rectangle activeScreenDimensions = Screen.FromControl(this).Bounds;
this.Size = new Size(activeScreenDimensions.Width + activeScreenDimensions.X, activeScreenDimensions.Height + activeScreenDimensions.Y);
Dieser Debugging- Code sollte den Trick gut machen:
Sie können die Eigenschaften der Bildschirmklasse untersuchen
Fügen Sie alle Anzeigen mit Screen.AllScreens in ein Array oder eine Liste ein und erfassen Sie dann den Index der aktuellen Anzeige und ihre Eigenschaften.
C # (von Telerik von VB konvertiert - bitte überprüfen)
{
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 (Originalcode)
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)