Domanda

il controllo Popup WPF è carino, ma un po 'limitato secondo me. c'è un modo per trascinare " un popup intorno quando viene aperto (come con il metodo DragMove () di Windows)?

questo può essere fatto senza grossi problemi o devo scrivere io stesso un sostituto della classe popup? grazie

È stato utile?

Soluzione

Ecco una soluzione semplice che utilizza un pollice.

  • Popup sottoclasse in XAML e codebehind
  • Aggiungi un pollice con larghezza / altezza impostate su 0 (questo potrebbe essere fatto anche in XAML)
  • Ascolta gli eventi MouseDown sul popup e genera lo stesso evento sul pollice
  • Sposta popup su DragDelta

XAML:

<Popup x:Class="PopupTest.DraggablePopup" ...>
    <Canvas x:Name="ContentCanvas">

    </Canvas>
</Popup>

C #:

public partial class DraggablePopup : Popup 
{
    public DraggablePopup()
    {
        var thumb = new Thumb
        {
            Width = 0,
            Height = 0,
        };
        ContentCanvas.Children.Add(thumb);

        MouseDown += (sender, e) =>
        {
            thumb.RaiseEvent(e);
        };

        thumb.DragDelta += (sender, e) =>
        {
            HorizontalOffset += e.HorizontalChange;
            VerticalOffset += e.VerticalChange;
        };
    }
}

Altri suggerimenti

Non è disponibile DragMove per PopUp. Solo una piccola soluzione, ci sono molti miglioramenti che puoi aggiungere a questo.

<Popup x:Name="pop" IsOpen="True" Height="200" Placement="AbsolutePoint"  Width="200">
   <Rectangle Stretch="Fill" Fill="Red"/>            
</Popup>

Nel codice dietro, aggiungi questo evento mousemove

   pop.MouseMove += new MouseEventHandler(pop_MouseMove);

   void pop_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            pop.PlacementRectangle = new Rect(new Point(e.GetPosition(this).X,
                e.GetPosition(this).Y),new Point(200,200));

        }
    }

Un altro modo per raggiungere questo obiettivo è impostare il posizionamento del Popup su MousePoint. Questo fa apparire inizialmente il popup nella posizione del cursore del mouse.

Quindi puoi utilizzare un evento Thumb o MouseMove per impostare il popup orizzontale di Ampup & amp; VerticalOffset. Queste proprietà allontanano il Popup dalla sua posizione originale mentre l'utente lo trascina.

Ricorda di riportare a zero HorizontalOffset e VerticalOffset per il prossimo utilizzo del popup!

Il problema di perdere il mouse quando ci si sposta troppo velocemente potrebbe essere risolto


Questo è preso da msdn:

  

La nuova finestra contiene il contenuto secondario di Popup.

     

Il controllo popup mantiene un riferimento al suo contenuto secondario come figlio logico. Quando viene creata la nuova finestra, il contenuto di Popup diventa un figlio visivo della finestra e rimane il figlio logico di Popup. Al contrario, Popup rimane il genitore logico del suo contenuto secondario.


In altre parole, il figlio del popup viene visualizzato in una finestra autonoma.

Quindi, quando si tenta di quanto segue:
Popup.CaptureMouse () sta acquisendo la finestra del wrapper e non il popup stesso. Invece, usando Popup.Child.CaptureMouse () si acquisisce il pop-up effettivo.

E tutti gli altri eventi dovrebbero essere registrati usando Popup.Child .

Come Popup.Child.MouseMove , Popup.Child.LostCapture e così via

Questo è stato testato e funziona perfettamente

Private Point startPoint;

 private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {

        startPoint = e.GetPosition(null);
    }
private void Window_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            Point relative = e.GetPosition(null);
            Point AbsolutePos = new Point(relative.X + this.Left, relative.Y + this.Top);
            this.Top = AbsolutePos.Y - startPoint.Y;
            this.Left = AbsolutePos.X - startPoint.X;
        }
    }

Funziona per trascinare la mia finestra, ma come mi è stato detto se sposterò il mouse velocemente, uscirebbe dalla finestra e smetterebbe di aumentare l'evento. Senza menzionare il trascinamento non è affatto liscio. Qualcuno sa come farlo correttamente, trascinamento piacevole e regolare, senza perderlo quando trascinato troppo velocemente ??? Pubblica un semplice esempio, se possibile, diverso da un intero tutorial che farebbe perdere il codice a principianti come me. Grazie!

Partendo dalla Jobi Joy , ho trovato una soluzione riutilizzabile che ti consente di aggiungere come controllo all'interno di xaml di una pagina / controllo esistente. Il che non è stato possibile aggiungere come Xaml con un nome poiché ha un ambito diverso.

    [ContentProperty("Child")]
    [DefaultEvent("Opened")]
    [DefaultProperty("Child")]
    [Localizability(LocalizationCategory.None)]
    public class DraggablePopup : Popup
    {
        public DraggablePopup()
        {
            MouseDown += (sender, e) =>
            {
                Thumb.RaiseEvent(e);
            };

            Thumb.DragDelta += (sender, e) =>
            {
                HorizontalOffset += e.HorizontalChange;
                VerticalOffset += e.VerticalChange;
            };
        }

        /// <summary>
        /// The original child added via Xaml
        /// </summary>
        public UIElement TrueChild { get; private set; }

        public Thumb Thumb { get; private set; } = new Thumb
        {
            Width = 0,
            Height = 0,
        };

        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);

            TrueChild = Child;

            var surrogateChild = new StackPanel();

            RemoveLogicalChild(TrueChild);

            surrogateChild.Children.Add(Thumb);
            surrogateChild.Children.Add(TrueChild);

            AddLogicalChild(surrogateChild);
            Child = surrogateChild;
        }
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top