2009-10-30 13 views
7

Domyślnym zachowaniem wyskakującego okienka jest umieszczenie go w miejscu, w którym wykracza poza krawędź ekranu, okno pop-up samo się zmieni. Czy istnieje sposób na wyłączenie tego zachowania?Tworzenie wyskakującego okna WPF bez ekranu

Mam okno podręczne, które użytkownik może przeciągać po ekranie. Jednak, gdy dojdzie do krawędzi, utknie. Utknie na krawędzi i pozostanie tam, aż mysz zostanie przeciągnięta daleko od krawędzi. Mam również dwa monitory i kiedy Popup jest przeciągnięty do krawędzi, dzielą się dwa monitory, co powoduje migotanie. Popup migocze pomiędzy dwoma monitorami.

Odpowiedz

3

Wystarczy użyć współdziałanie przenieść wyskakujące okienka (przeciągnij je)

Oto kod dla kciuka, który będzie śledzić proces przeciągania

regionu Thumb

private Thumb mThumb = null; 
    public Thumb Thumb 
    { 
     get { return mThumb; } 
     set 
     { 
      if (mThumb != value) 
      { 
       if (mThumb != null) 
       { 
        DetachThumb(); 
       } 
       mThumb = value; 
       if (mThumb != null) 
       { 
        AttachThumb(); 
       } 
      } 
     } 
    } 

    private void AttachThumb() 
    { 
     Thumb.DragStarted += Thumb_DragStarted; 
     Thumb.DragDelta += Thumb_DragDelta; 
     Thumb.DragCompleted += Thumb_DragCompleted; 
    } 

    private void DetachThumb() 
    { 
     Thumb.DragStarted -= Thumb_DragStarted; 
     Thumb.DragDelta -= Thumb_DragDelta; 
     Thumb.DragCompleted -= Thumb_DragCompleted; 
    } 

    private void Thumb_DragStarted(object sender, DragStartedEventArgs e) 
    { 
     mIsThumbDragging = true; 
     mPreviousDiffX = 0; 
     mPreviousDiffY = 0; 
    } 

    private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) 
    { 
     if (mIsMoving) 
     { 
      return; 
     } 
     mIsMoving = true; 
     try 
     { 
      if (mIsThumbDragging) 
      { 
       var doubleDetaX = e.HorizontalChange + mPreviousDiffX; 
       var doubleDetaY = e.VerticalChange + mPreviousDiffY; 

       var deltaX = (int)doubleDetaX; 
       var deltaY = (int)doubleDetaY; 

       mPreviousDiffX = (double)deltaX - doubleDetaX; 
       mPreviousDiffY = (double)deltaY - doubleDetaY; 

       HostPopup.Move(deltaX, deltaY); 
      } 
     } 
     finally 
     { 
      mIsMoving = false; 
     } 
    } 

    private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e) 
    { 
     mIsThumbDragging = false; 
    } 

    #endregion 

klasie HostPopup jest podklasą Popup i stosuje następujące metody, w których współdziałanie umożliwia przeniesienie okna:

[DllImport("user32.dll", SetLastError = true)] 
    internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); 

    internal void Move(int deltaX, int deltaY) 
    { 
     if (mIsMoving) 
     { 
      return; 
     } 
     mIsMoving = true; 
     try 
     { 
      if (Child == null) 
       return; 

      var hwndSource = (PresentationSource.FromVisual(Child)) as HwndSource; 

      if (hwndSource == null) 
       return; 
      var hwnd = hwndSource.Handle; 

      RECT rect; 

      if (!GetWindowRect(hwnd, out rect)) 
       return; 

      MoveWindow(hwnd, rect.Left + deltaX, rect.Top + deltaY, (int)Width, (int)Height, true); 
     } 
     finally 
     { 
      mIsMoving = false; 
     } 
    } 
+1

Czy ktoś może dokładniej wyjaśnić, jak to zaimplementować? Jak uzyskać dostęp do podklasy HostPopup? Gdzie znajduje się metoda GetWindowRect()? – Saggio

2

Jeśli chcesz, aby okno dialogowe zachowywało się bardziej jak okno, po prostu utworzyłem okno zamiast wyskakującego okienka.

Posiadanie wyskakującego okienka, które nie pozycjonuje się jak standardowe wyskakujące okienko i pozwala przeciągnąć je po ekranie, wydaje się być receptą na niską użyteczność i zamieszanie.

+3

Niestety, re to funkcjonalność Popupu, którego Window nie ma i jest dla mnie ważniejsza niż swoboda ruchu. Sądzę, że będę musiał ograniczyć ruch, więc nie ma szans na wyjście poza granice ekranu, a więc brak zmiany pozycji i migotania. Dzięki za informację. –

+1

Uzgodnione. Chcę, aby popup podążał za oknem i uniemożliwiał wprowadzanie do kontrolki WinForm hostowanej w aplikacji WPF (zasadniczo wskaźnik zajętości) i jeśli okno zostanie przeciągnięte poza ekran, popup nie będzie podążał za oknem poza granice ekranu. –

+0

Kolejny punkt danych na ten temat. Czasami wyskakujące okno jest lepsze niż okno przeciągania zawartości, ponieważ otwarcie okna w systemie Windows 10 w trybie tabletu spowoduje podzielenie ekranu ekranu Win10 i przerwanie przeciągania. (Kontekst: Używam Popup tymczasowo jako okno sprzężenia zwrotnego, nie będącego stałą częścią interfejsu użytkownika) – jschroedl

Powiązane problemy