Mam okno bez tytułu, ponieważ chciałem stworzyć własny styl okna.Jak sprawdzić, czy okno jest przeciągane C# WPF
Przyciski tytuł i zminimalizuj, zmaksymalizuj i zamknij znajdują się w panelu dokowania. Dodałem następującą procedurę obsługi zdarzeń, aby zmaksymalizować, przywrócić i przeciągnąć okno.
Problem pojawia się, gdy okno jest zmaksymalizowane.
To, co znalazłem, to to, że za każdym razem jedno kliknięcie tytułu zostaje przywrócone. Kiedy chcę tylko, żeby został przywrócony, jeśli zostanie podwójnie kliknięty lub przeciągnięty. Rozumiem, dlaczego tak się dzieje, ale nie wiem, jak rozwiązać ten problem.
public void TITLEBAR_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DockPanel dp = (DockPanel)sender;
Window parentWindow = Window.GetWindow(dp);
bool doubleClick = IsDoubleClick(sender, e);
if (e.ChangedButton == MouseButton.Left && e.LeftButton == MouseButtonState.Pressed && !doubleClick)
{
if (parentWindow.WindowState == WindowState.Maximized)
{
double mouseX = e.GetPosition(parentWindow).X;
double width = parentWindow.RestoreBounds.Width;
System.Drawing.Rectangle screenBounds = getCurrentScreenBounds(parentWindow);
double x = screenBounds.Left + (mouseX - ((width/100.00) * ((100.00/screenBounds.Width) * mouseX)));
if (x < 0)
{
x = 0;
}
else
{
if (x + width > screenBounds.Left + screenBounds.Width)
{
x = screenBounds.Left + screenBounds.Width - width;
}
}
parentWindow.Left = x;
parentWindow.Top = screenBounds.Top;
parentWindow.WindowState = System.Windows.WindowState.Normal;
}
parentWindow.DragMove();
//MessageBox.Show("");
}
if (doubleClick)
{
if (parentWindow.WindowState == System.Windows.WindowState.Maximized)
{
parentWindow.WindowState = System.Windows.WindowState.Normal;
}
else
{
parentWindow.WindowState = System.Windows.WindowState.Maximized;
}
}
}
Wraz z tej klasy:
public static class MouseButtonHelper
{
private const long k_DoubleClickSpeed = 500;
private const double k_MaxMoveDistance = 10;
private static long _LastClickTicks = 0;
private static System.Windows.Point _LastPosition;
private static WeakReference _LastSender;
public static bool IsDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
System.Windows.Point position = e.GetPosition(null);
long clickTicks = DateTime.Now.Ticks;
long elapsedTicks = clickTicks - _LastClickTicks;
long elapsedTime = elapsedTicks/TimeSpan.TicksPerMillisecond;
bool quickClick = (elapsedTime <= k_DoubleClickSpeed);
bool senderMatch = (_LastSender != null && sender.Equals(_LastSender.Target));
if (senderMatch && quickClick && position.Distance(_LastPosition) <= k_MaxMoveDistance)
{
// Double click!
_LastClickTicks = 0;
_LastSender = null;
return true;
}
// Not a double click
_LastClickTicks = clickTicks;
_LastPosition = position;
if (!quickClick)
_LastSender = new WeakReference(sender);
return false;
}
private static double Distance(this System.Windows.Point pointA, System.Windows.Point pointB)
{
double x = pointA.X - pointB.X;
double y = pointA.Y - pointB.Y;
return Math.Sqrt(x * x + y * y);
}
}
I to wypracować granice bieżącego ekranu.
public static class WindowHelper
{
public static System.Drawing.Rectangle getCurrentScreenBounds(System.Windows.Window pWnd)
{
System.Windows.Forms.Screen parentScreen = GetCurrentScreen(pWnd);
if (parentScreen == null)
{
return System.Windows.Forms.Screen.PrimaryScreen.Bounds;
}
return parentScreen.Bounds;
}
private static System.Windows.Forms.Screen GetCurrentScreen(System.Windows.Window pWnd)
{
System.Drawing.Rectangle intersectingRect = new System.Drawing.Rectangle();
System.Drawing.Rectangle windowRect = new System.Drawing.Rectangle(Convert.ToInt32(pWnd.Left), Convert.ToInt32(pWnd.Top), Convert.ToInt32(pWnd.Width), Convert.ToInt32(pWnd.Height));
int largestIntersectingArea = 0;
System.Windows.Forms.Screen curScreen = null;
foreach (System.Windows.Forms.Screen s in System.Windows.Forms.Screen.AllScreens)
{
if (s.Bounds.IntersectsWith(windowRect))
{
intersectingRect = System.Drawing.Rectangle.Intersect(s.Bounds, windowRect);
int intersectingArea = intersectingRect.Width * intersectingRect.Height;
if (intersectingArea > largestIntersectingArea)
{
largestIntersectingArea = intersectingArea;
curScreen = s;
}
}
}
return curScreen;
}
}
można dodać odpowiedź następnie oznaczyć je po 2 dniach będzie to lepszy sposób. możesz dostać do niego upvotes :). – Star
Dzięki za napiwek! @Star – Hank
Hank, skopiuj aktualizację do odpowiedzi, a otrzymasz ode mnie propozycję odpowiedzi na pytanie i odpowiedź. –