WPF에서 현재 화면의 크기를 얻는 방법은 무엇입니까?
를 사용하여 기본 화면의 크기를 확인할 수 있습니다.
System.Windows.SystemParameters.PrimaryScreenWidth;
System.Windows.SystemParameters.PrimaryScreenHeight;
하지만 현재 화면의 크기는 어떻게 알 수 있습니까? (멀티 화면 사용자가 항상 기본 화면을 사용하는 것은 아니며 모든 화면에서 동일한 해상도를 사용하는 것은 아닙니다. 그렇죠?)
XAML에서 크기에 액세스할 수 있으면 좋겠지만 코드(C#)에서 액세스하면 충분합니다.
시스템에서 화면 주위에 작은 래퍼를 만들었습니다.창문들.양식, 현재 모든 것이 작동합니다.하지만 "장치 독립 픽셀"에 대해서는 확실하지 않습니다.
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; }
}
}
또한 작업 표시줄 너비를 제외한 직사각형을 반환하는 현재 화면 치수, 특히 작업 영역이 필요했습니다.
마우스가 위치한 곳까지 오른쪽 아래로 열리는 창의 위치를 바꾸기 위해 사용했습니다.창이 상당히 크기 때문에 많은 경우 화면 경계를 벗어났습니다.다음 코드는 @e-j 답변을 기반으로 합니다.현재 화면이 표시됩니다.차이점은 제 위치 조정 알고리즘도 보여준다는 것입니다. 제가 생각하기에 이것이 바로 요점입니다.
코드:
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 │
└──────────────────────┴──────────┘ └──────────────────────┴──────────┘
- 코드 형식을 사용할 수밖에 없었습니다(그렇지 않았다면 공백이 사라졌을 것입니다).
- 원래 이것은 위의 코드에서 a로 나타났습니다.
<remark><code>...</code></remark>
여기, 친구.작업 영역의 너비와 높이만 표시됩니다.
System.Windows.SystemParameters.WorkArea.Width
System.Windows.SystemParameters.WorkArea.Height
창 왼쪽 상단을 기준으로 현재 화면이 표시됩니다. 이 화면을 호출하십시오.현재 화면() - 현재 화면에 대한 정보를 가져옵니다.
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));
}
}
}
현재 모니터의 치수를 알 수 있는 네이티브 WPF 기능은 없는 것으로 알고 있습니다.대신 네이티브 다중 디스플레이 모니터 기능을 호출하여 관리되는 클래스로 래핑하고 XAML에서 모니터 기능을 사용하는 데 필요한 모든 속성을 노출할 수 있습니다.
이것이 오래된 질문인 것은 감사합니다. 하지만 WPF가 여전히 이 '즉시'를 수행하는 좋은 방법을 제공하지 않고 위의 답변이 약간 지나치게 복잡해 보이는 것을 보면 아래의 솔루션이 조금 더 소화하기 쉽다는 것을 알게 될 것입니다.
- WPF 친화적, 즉 장치 독립 단위 반환(WinForm 스타일 픽셀 아님)
- 서로 다른 DPI에서 모니터 지원
- 모든 크기/위치 작업 표시줄에 사용할 수 있는 캐터
- 시스템의 확장 메서드입니다.창문들.창문.
즐기세요 :)
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
using Point = System.Drawing.Point;
namespace ClrVpin.Shared
{
public static class WindowExtensions
{
public static Rect GetCurrentScreenWorkArea(this Window window)
{
var screen = Screen.FromPoint(new Point((int) window.Left, (int) window.Top));
var dpiScale = VisualTreeHelper.GetDpi(window);
return new Rect {Width = screen.WorkingArea.Width / dpiScale.DpiScaleX, Height = screen.WorkingArea.Height / dpiScale.DpiScaleY};
}
}
}
그냥 이것을 사용하는 게 어때요?
var interopHelper = new WindowInteropHelper(System.Windows.Application.Current.MainWindow);
var activeScreen = Screen.FromHandle(interopHelper.Handle);
저는 이 게시물을 우연히 발견했고 어떤 답변도 제가 하려는 것을 완전히 포착하지 못했습니다.저는 3840x2160 해상도의 노트북과 1920x1080 해상도의 모니터 두 대를 가지고 있습니다.WPF 애플리케이션에서 올바른 모니터 크기를 얻으려면 애플리케이션 DPI를 인식시켜야 했습니다.그런 다음 Win32 API를 사용하여 모니터 크기를 확인했습니다.
저는 먼저 크기를 얻고자 하는 모니터로 창문을 옮겼습니다.그런 다음 응용 프로그램의 기본 창(기본 창이 아니어도 되지만 내 응용 프로그램에는 하나의 창만 있음)과 IntPtr을 모니터로 가져옵니다.그런 다음 MONITORINFOEX 구조의 새 인스턴스를 만들고 GetMonitor라고 불렀습니다.정보 방법.
MONITOR INFOEX 구조는 작업 영역과 화면의 전체 해상도를 모두 갖추고 있어 필요한 것을 반환할 수 있습니다.이렇게 하면 시스템에 대한 참조도 생략할 수 있습니다.창문들.양식(응용프로그램에 다른 것이 필요하지 않은 것으로 가정)..NET Framework Reference Source for System을 사용했습니다.창문들.Forms.화면에서 이 해결책을 찾을 수 있습니다.
public System.Drawing.Size GetMonitorSize()
{
var window = System.Windows.Application.Current.MainWindow;
var hwnd = new WindowInteropHelper(window).EnsureHandle();
var monitor = NativeMethods.MonitorFromWindow(hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST);
NativeMethods.MONITORINFO info = new NativeMethods.MONITORINFO();
NativeMethods.GetMonitorInfo(new HandleRef(null, monitor), info);
return info.rcMonitor.Size;
}
internal static class NativeMethods
{
public const Int32 MONITOR_DEFAULTTONEAREST = 0x00000002;
[DllImport("user32.dll")]
public static extern IntPtr MonitorFromWindow(IntPtr handle, Int32 flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool GetMonitorInfo(HandleRef hmonitor, MONITORINFO info);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
public class MONITORINFO
{
internal int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
internal RECT rcMonitor = new RECT();
internal RECT rcWork = new RECT();
internal int dwFlags = 0;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public RECT(System.Drawing.Rectangle r)
{
left = r.Left;
top = r.Top;
right = r.Right;
bottom = r.Bottom;
}
public static RECT FromXYWH(int x, int y, int width, int height) => new RECT(x, y, x + width, y + height);
public System.Drawing.Size Size => new System.Drawing.Size(right - left, bottom - top);
}
}
시간을 내어 시스템 매개 변수 구성원을 스캔합니다.
VirtualScreenWidth
VirtualScreenHeight
화면의 상대적인 위치까지 고려합니다.
두 대의 모니터로만 테스트됩니다.
시스템 사용에 익숙한 경우.윈도우.양식 클래스가 있으면 시스템 참조를 추가할 수 있습니다.창문들.프로젝트에 대한 양식 클래스:
솔루션 탐색기 -> 참조 -> 참조 추가... -> (어셈블리: Framework ) -> 아래로 스크롤하여 시스템을 확인합니다.윈도우.양식 어셈블리 -> 확인.
이제 시스템을 사용하여 추가할 수 있습니다.윈도우.wpf 프로젝트의 양식, 설명 및 사용 화면은 이전과 동일합니다.
저는 그 요구를 이해합니다.중요한 것은, 그러한 가치를 얻기 위한 WPF 방법이 있다는 것입니다. 하지만 네, 기여자 중 한 명이 옳습니다. 직접적인 것은 아닙니다.해결책은 이러한 모든 해결책을 얻는 것이 아니라 깨끗한 설계 및 개발에 따라 초기 접근 방식을 변경하는 것입니다.
초기 기본 창을 화면으로 설정
많은 유용한 WPF 메서드를 포함하여 실제 창의 값 가져오기
크기 조정과 같이 원하는 동작에 대해 원하는 만큼 Windows(윈도우)를 추가할 수 있지만 이제 로드 및 렌더링된 화면에 언제든지 액세스할 수 있습니다.
다음 예에서는 이러한 접근 방식을 사용해야 하는 코드가 몇 가지 있으므로 주의하십시오(화면의 각 모서리에 대한 포인트가 제공됩니다).단일, 듀얼 모니터 및 다양한 해상도에 대한 작업 예(기본 주 창 클래스 내):
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 설정을 고려하여 현재 화면의 해상도를 얻고 장치 독립 장치를 사용합니다.최대화된 창 자체처럼 여백이 추가되지 않습니다.
(캔버스 사용 가능)UIElement
어렸을 때는 어떤 콘텐츠와도 함께 사용할 수 있어야 합니다.)
WPF App()의 경우.NET 프레임워크) :
double H;
double W;
크기 변경(클라이언트 측에서 화면 크기 변경 추적)이라는 Window 이벤트를 선언할 수 있습니다.
이렇게 하면 런타임에 화면 크기를 가져올 수 있습니다.
private void WindowSizeChange(object sender, SizeChangedEventArgs e)
{
double H = this.ActualHeight;
double W = this.ActualWidth;
}
XAML 화면의 중앙 창WindowStartupLocation="CenterOwner"
그런 다음 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대의 모니터에서 테스트되었습니다.
언급URL : https://stackoverflow.com/questions/1927540/how-to-get-the-size-of-the-current-screen-in-wpf
'programing' 카테고리의 다른 글
앱 제거 시 키 체인 항목 삭제 (0) | 2023.05.17 |
---|---|
다른 분기 없이 하나의 Git 분기만 푸시하는 방법은 무엇입니까? (0) | 2023.05.17 |
메타데이터예외:지정한 메타데이터 리소스를 로드할 수 없습니다. (0) | 2023.05.17 |
GitHub 저장소를 복제하기 전에 크기를 확인하려면 어떻게 해야 합니까? (0) | 2023.05.12 |
다중 ng-콘텐츠 (0) | 2023.05.12 |