Eu sei que posso obter o tamanho da tela principal usando
System.Windows.SystemParameters.PrimaryScreenWidth;
System.Windows.SystemParameters.PrimaryScreenHeight;
Mas como obtenho o tamanho da tela atual? (Os usuários de várias telas nem sempre usam a tela principal e nem todas as telas usam a mesma resolução, certo?)
Seria bom poder acessar o tamanho do XAML, mas fazer isso a partir do código (C #) seria suficiente.
Respostas:
Pelo que eu sei, não existe uma função WPF nativa para obter as dimensões do monitor atual. Em vez disso, você poderia PInvoke funções de monitores de exibição múltiplos nativos , envolvê-los em classe gerenciada e expor todas as propriedades necessárias para consumi-los do XAML.
fonte
Eu criei um pequeno wrapper em torno da Tela de System.Windows.Forms, atualmente tudo funciona ... Não tenho certeza sobre os "pixels independentes de dispositivo", porém.
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; } } }
fonte
Aqui amigo. Isso fornecerá apenas a largura e a altura da área de trabalho
System.Windows.SystemParameters.WorkArea.Width System.Windows.SystemParameters.WorkArea.Height
fonte
Isso lhe dará a tela atual com base no canto superior esquerdo da janela, basta chamar this.CurrentScreen () para obter informações sobre a tela atual.
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)); } } }
fonte
Reserve um tempo para examinar os membros SystemParameters.
VirtualScreenWidth
VirtualScreenHeight
Estes levam em consideração até as posições relativas das telas.
Testado apenas com dois monitores.
fonte
Por que não apenas usar isso?
var interopHelper = new WindowInteropHelper(System.Windows.Application.Current.MainWindow); var activeScreen = Screen.FromHandle(interopHelper.Handle);
fonte
System.Windows.Forms.Screen
lidar com o pixel independente de dispositivoSe você está familiarizado com o uso da classe System.Windows.Forms , pode simplesmente adicionar uma referência da classe System.Windows.Forms ao seu projeto:
Gerenciador de Soluções -> Referências -> Adicionar Referências ... -> (Assemblies: Framework) -> role para baixo e verifique System.Windows.Forms assembly -> OK .
Agora você pode adicionar usando System.Windows.Forms; declaração e use a tela em seu projeto wpf como antes.
fonte
Eu também precisava da dimensão da tela atual, especificamente a área de trabalho, que retornou o retângulo excluindo a largura da barra de tarefas.
Usei-o para reposicionar uma janela, que é aberta à direita e para baixo onde o mouse está posicionado. Como a janela é bastante grande, em muitos casos ela saiu dos limites da tela. O código a seguir é baseado na resposta @ej: Isso fornecerá a tela atual ... . A diferença é que também mostro meu algoritmo de reposicionamento, que presumo que seja realmente o ponto.
O código:
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; } } }
Algumas explicações:
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>
fonte
Eu entendo as demandas. O fato é que existem métodos WPF para obter esses valores - mas sim, um dos colaboradores está certo, não diretamente. A solução não é obter todas essas soluções alternativas, mas mudar a abordagem inicial de acordo com um design e desenvolvimento limpos.
A) Defina a janela principal inicial para tela
B) Obtenha os valores para a janela atual, incluindo uma tonelada de métodos WPF úteis
C) Você pode adicionar quantas janelas quiser para o comportamento que deseja, como redimensionável, minimizado o que for ... mas agora você sempre pode acessar a Tela Carregada e Renderizada
Tenha cuidado com o exemplo a seguir, existe algum Código que torna necessário o uso desse tipo de abordagem, no entanto, deve funcionar (daria a você os pontos para cada um dos cantos de sua tela): Exemplo de trabalho em single, Monitor duplo e diferentes resoluções (dentro da classe da janela principal primária):
InitializeComponent(); […] ActualWindow.AddHandler(Window.LoadedEvent, new RoutedEventHandler(StartUpScreenLoaded));
Evento encaminhado:
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); }
fonte
Se você usar qualquer janela de tela inteira (com a sua
WindowState = WindowState.Maximized, WindowStyle = WindowStyle.None
), poderá agrupar seu conteúdoSystem.Windows.Controls.Canvas
desta forma:<Canvas Name="MyCanvas" Width="auto" Height="auto"> ... </Canvas>
Então você pode usar
MyCanvas.ActualWidth
eMyCanvas.ActualHeight
para obter a resolução da tela atual, com as configurações de DPI levadas em consideração e em unidades independentes de dispositivo. Ele não adiciona nenhuma margem como a própria janela maximizada faz.(O Canvas aceita
UIElement
s como filhos, então você deve ser capaz de usá-lo com qualquer conteúdo.)fonte
Centralize a janela na tela em XAML
WindowStartupLocation="CenterOwner"
e chame WindowLoaded ()double ScreenHeight = 2 * (Top + 0.5 * Height);
fonte
double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth; double screenhight= System.Windows.SystemParameters.PrimaryScreenHeight;
fonte
Funciona com
this.Width = System.Windows.SystemParameters.VirtualScreenWidth; this.Height = System.Windows.SystemParameters.VirtualScreenHeight;
Testado em 2 monitores.
fonte
VirtualScreen
abrange todas as telas - então isso nunca funcionará se você tiver mais de uma tela!