Tengo un problema con mi ventana personalizada (AllowTransparency, WindowStyle = None) en WPF. El método DragMove() funciona bien, pero cuando maximizo la ventana, o maximizo automáticamente con Windows 7 Aero Snap, este método no funciona en absoluto. Así que no puedo abrir la ventana con la función de arrastrar del mouse y devolverlo a WindowState.Normal. Izquierda y derecha Aero Snap funciona bien, puedo abrir y cerrar ventanas sin problemas. Pero cuando se maximiza, nada funciona, excepto la combinación Win + Down. Tal vez alguien sepa cómo resolver este problema o ¿dónde puedo encontrar otras formas de hacer una adecuada DragMove de ventanas personalizadas con funciones de funcionamiento de Aero Snap?DragMove() y Maximice
Respuesta
Aquí está mi método. Trate de hacerla más corta)))
private void InitHeader()
{
var border = Find<Border>("borderHeader");
var restoreIfMove = false;
border.MouseLeftButtonDown += (s, e) =>
{
if (e.ClickCount == 2)
{
if ((ResizeMode == ResizeMode.CanResize) ||
(ResizeMode == ResizeMode.CanResizeWithGrip))
{
SwitchState();
}
}
else
{
if (WindowState == WindowState.Maximized)
{
restoreIfMove = true;
}
DragMove();
}
};
border.MouseLeftButtonUp += (s, e) =>
{
restoreIfMove = false;
};
border.MouseMove += (s, e) =>
{
if (restoreIfMove)
{
restoreIfMove = false;
var mouseX = e.GetPosition(this).X;
var width = RestoreBounds.Width;
var x = mouseX - width/2;
if (x < 0)
{
x = 0;
}
else
if (x + width > screenSize.X)
{
x = screenSize.X - width;
}
WindowState = WindowState.Normal;
Left = x;
Top = 0;
DragMove();
}
};
}
private void SwitchState()
{
switch (WindowState)
{
case WindowState.Normal:
{
WindowState = WindowState.Maximized;
break;
}
case WindowState.Maximized:
{
WindowState = WindowState.Normal;
break;
}
}
}
(Para obtener ScreenSize utilizo métodos nativos)
solución de groaner no funciona correctamente con múltiples configuraciones del monitor, sobre todo cuando el monitor principal no es la más a la izquierda.
Aquí está mi solución basada en la que maneja las configuraciones de monitor único o múltiple correctamente. En este código, 'rctHeader' es un rectángulo definido en el XAML.
private bool mRestoreIfMove = false;
public MainWindow()
{
InitializeComponent();
}
private void SwitchWindowState()
{
switch (WindowState)
{
case WindowState.Normal:
{
WindowState = WindowState.Maximized;
break;
}
case WindowState.Maximized:
{
WindowState = WindowState.Normal;
break;
}
}
}
private void rctHeader_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
if ((ResizeMode == ResizeMode.CanResize) || (ResizeMode == ResizeMode.CanResizeWithGrip))
{
SwitchWindowState();
}
return;
}
else if (WindowState == WindowState.Maximized)
{
mRestoreIfMove = true;
return;
}
DragMove();
}
private void rctHeader_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
mRestoreIfMove = false;
}
private void rctHeader_MouseMove(object sender, MouseEventArgs e)
{
if (mRestoreIfMove)
{
mRestoreIfMove = false;
double percentHorizontal = e.GetPosition(this).X/ActualWidth;
double targetHorizontal = RestoreBounds.Width * percentHorizontal;
double percentVertical = e.GetPosition(this).Y/ActualHeight;
double targetVertical = RestoreBounds.Height * percentVertical;
WindowState = WindowState.Normal;
POINT lMousePosition;
GetCursorPos(out lMousePosition);
Left = lMousePosition.X - targetHorizontal;
Top = lMousePosition.Y - targetVertical;
DragMove();
}
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetCursorPos(out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
}
He escrito un post sobre esto:
http://dragablz.net/2014/12/16/getting-windows-snap-to-play-with-wpf-borderless-windows/
Lo siento, pero la publicación del blog es casi inútil, en realidad se requiere desmantelar todo el proyecto que mencionas en la publicación del blog y obtener lo que se necesita. – CularBytes
En WPF, lo recomiendo el uso de Control.PointToScreen cuando se restaura la ventana antes de su Window.DragMove. PointToScreen también manejará múltiples configuraciones de monitores. Esto simplificaría la restauración a lo siguiente:
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if(e.ClickCount == 2)
{
if(ResizeMode != ResizeMode.CanResize &&
ResizeMode != ResizeMode.CanResizeWithGrip)
{
return;
}
WindowState = WindowState == WindowState.Maximized
? WindowState.Normal
: WindowState.Maximized;
}
else
{
mRestoreForDragMove = WindowState == WindowState.Maximized;
DragMove();
}
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
if(mRestoreForDragMove)
{
mRestoreForDragMove = false;
var point = PointToScreen(e.MouseDevice.GetPosition(this));
Left = point.X - (RestoreBounds.Width * 0.5);
Top = point.Y;
WindowState = WindowState.Normal;
DragMove();
}
}
private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
mRestoreForDragMove = false;
}
private bool mRestoreForDragMove;
Esta solución funciona perfectamente, exactamente lo que estaba buscando. Gracias por compartir. – Al0x
Comparado con las otras soluciones, esto funciona mejor: tiene fallas menores, pero funciona muy bien. –
Un poco tarde para otra respuesta, pero mi código era más simple así que lo pondré aquí. Como mencionan, la alineación a la izquierda y a la derecha funciona bien, pero cuando la ventana se Maximiza o se ajusta a los límites superiores de la pantalla y se maximiza, ¡el método DragMove no funcionará!
Sólo controlar el evento MOUSE_DOWN en el elemento que desea arrastrar con este aspecto:
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (WindowState == WindowState.Maximized)
{
var point = PointToScreen(e.MouseDevice.GetPosition(this));
if (point.X <= RestoreBounds.Width/2)
Left = 0;
else if (point.X >= RestoreBounds.Width)
Left = point.X - (RestoreBounds.Width - (this.ActualWidth - point.X));
else
Left = point.X - (RestoreBounds.Width/2);
Top = point.Y - (((FrameworkElement)sender).ActualHeight/2);
WindowState = WindowState.Normal;
}
DragMove();
}
espero que ayude a alguien!
Ocasionalmente sucede que la ventana vuelve a un estado normal pero no ancla al mouse, lo cual es realmente irritante. –
- 1. Maximice el rendimiento con RabbitMQ
- 2. Maximice la ventana y llévela al frente con powershell
- 3. Maximice WebDriver (Selenium 2) en Python
- 4. Maximice Emacs en el arranque? (no en pantalla completa)
- 5. Ventana problema Focus con .NET 4.0 y WindowsFormstHost
- 6. Forma de hacer que una ventana WPF sin ventana sea arrastrable sin obtener InvalidOperationException
- 7. JFrame Maximizar ventana
- 8. Forma correcta de asegurar que mainform se haya maximizado y reescrito completamente antes de mostrar un formulario modal en la carga
- 9. Mover dos ventanas WPF a la vez?
- 10. ¿Cómo se puede maximizar la forma de cualquier pantalla de computadora en una aplicación de Windows Forms?
- 11. Arrastre WPF Popup control
- 12. Reemplazando "#", "$", "%", "&", y "_" con "\ #", "\ $", "\%", "\ &" y "\ _"
- 13. ¿Qué es y = y | =
- 14. CSS "y" y "o"
- 15. ¿Cómo evitar que Googlebot sea un sitio abrumador?
- 16. ¿Hay alguna manera de maximizar la pestaña actual en Visual Studio?
- 17. ¿Cómo mostrar la ventana emergente a pantalla completa en javascript?
- 18. Rails y markdown y editor
- 19. dividir y conquistar y recursión
- 20. Capacidades y Linux y Java
- 21. XHTML y Y (Ampersand) codificación
- 22. UILabel y numberOfLines y sizeToFit:
- 23. VBA: Diferencia entre y y +
- 24. ¿A qué se refiere "s- [keyname]" en Emacs, y cómo le digo a Emacs que lo ignore?
- 25. Clases de Coffeescript y alcance y flechas gruesas y delgadas
- 26. Rendimiento y clasificación, y distinto único entre mysql y php
- 27. Diferencia entre @Max y @DecimalMax (y @Min y @DecimalMin)
- 28. Cambio automático de tamaño de los controles de Windows Forms
- 29. Cómo utilizar la sangría como delimitadores de bloque con bison y flex
- 30. Bash - Listar y ordenar archivos y sus tamaños y por nombre y tamaño
¡Impresionante! ¡Muchas gracias! –
@groaner ¿Puedes indicar el método nativo screenSize que usaste? – egfconnor