2010-09-23 14 views
6

Ho una winform su cui voglio consentire all'utente di spostare un controllo.Come consentire all'utente di spostare un controllo sul modulo

Il controllo è (per ora) una linea verticale: l'etichetta con bordo e una larghezza di 1.

Il contesto non è molto importante, ma lo darò a voi in ogni modo. Ho uno sfondo con alcuni elementi grafici e mi piacerebbe che l'utente fosse in grado di far scorrere una linea guida sopra la grafica. La grafica è realizzata con la libreria NPlots. Assomiglia a questo: http://www.ibme.de/pictures/xtm-window-graphic-ramp-signals.png

Se riesco a scoprire come l'utente può fare clic e trascinare il controllo etichetta/linea sullo schermo, posso risolvere il mio problema delle linee guida. Per favore aiuto.

risposta

8

Il codice per questo può diventare un po 'complesso, ma in sostanza è necessario acquisire gli eventi MouseDown, MouseMove e MouseUp nel modulo. Qualcosa di simile:

public void Form1_MouseDown(object sender, MouseEventArgs e) 
{ 
    if(e.Button != MouseButton.Left) 
     return; 

    // Might want to pad these values a bit if the line is only 1px, 
    // might be hard for the user to hit directly 
    if(e.Y == myControl.Top) 
    { 
     if(e.X >= myControl.Left && e.X <= myControl.Left + myControl.Width) 
     { 
      _capturingMoves = true; 
      return; 
     } 
    } 

    _capturingMoves = false; 
} 

public void Form1_MouseMove(object sender, MouseEventArgs e) 
{ 
    if(!_capturingMoves) 
     return; 

    // Calculate the delta's and move the line here 
} 

public void Form1_MouseUp(object sender, MouseEventArgs e) 
{ 
    if(_capturingMoves) 
    { 
     _capturingMoves = false; 
     // Do any final placement 
    } 
} 
+0

Grazie! Funziona perfettamente. – Roast

3

In WinForms, è possibile gestire gli eventi MouseDown, MouseMove e MouseUp di un controllo. Su MouseDown, imposta un bit o un riferimento che indica al tuo modulo su quale controllo è stato fatto clic sul mouse e cattura le X e Y del mouse da MouseEventArgs. Su MouseMove, se è impostato un controllo, regola le sue X e Y in base alla differenza tra l'ultima X e Y acquisita e le coordinate correnti. Su MouseUp, rilascia il controllo.

Avrei impostato una "modalità di modifica" per questo; quando l'utente accede a questa modalità, i gestori di eventi correnti dei controlli del modulo devono essere scollegati e i gestori del movimento collegati. Se vuoi mantenere o annullare queste modifiche (come se stessi progettando un modulo personalizzato che il tuo cliente può utilizzare per personalizzare i layout delle finestre), dovrai anche essere in grado di scattare una sorta di istantanea dei layout prima e dopo di i controlli.

0

Ecco un metodo di estensione che è possibile utilizzare per qualsiasi controllo. Utilizza Rx e si basa sul post A Brief Introduction to the Reactive Extensions for .NET, Rx e campione di Wes Dyer.

public static class FormExtensions 
{ 
    public static void EnableDragging(this Control c) 
    { 
     // Long way, but strongly typed.   
     var downs = 
      from down in Observable.FromEvent<MouseEventHandler, MouseEventArgs>(
       eh => new MouseEventHandler(eh), 
       eh => c.MouseDown += eh, 
       eh => c.MouseDown -= eh) 
      select new { down.EventArgs.X, down.EventArgs.Y }; 

     // Short way.   
     var moves = from move in Observable.FromEvent<MouseEventArgs>(c, "MouseMove") 
        select new { move.EventArgs.X, move.EventArgs.Y }; 

     var ups = Observable.FromEvent<MouseEventArgs>(c, "MouseUp"); 

     var drags = from down in downs 
        from move in moves.TakeUntil(ups) 
        select new Point { X = move.X - down.X, Y = move.Y - down.Y }; 

     drags.Subscribe(drag => c.SetBounds(c.Location.X + drag.X, c.Location.Y + drag.Y, 0, 0, BoundsSpecified.Location)); 
    } 
} 

Usage:

Button Button1 = new Button();

button1.EnableDragging();

0

Bene in tutta onestà c'è un modo più semplice in cui con l'inizializzazione di una variabile booleana globale chiamato qualunque cosa ti piace, in questo caso, isMouseClicked. Sul tuo controllo desideri consentire il trascinamento mentre vai al suo evento di mouse down,

Assicurati che questi eventi siano i tuoi eventi di controllo e non i tuoi eventi di moduli.

if (e.button == MouseButtons.left) 
    //this is where you set the boolean to true 

Poi vai al suo evento del mouse mossa

if (isMouseClicked == true) 
    //You then set your location of your control. See below: 
    Button1.Location = new Point(MousePosition.X, MousePosition.Y); 

del mouse fino assicurarsi di impostare il isMouseClicked-false;

Problemi correlati