2010-09-23 20 views
6

Tengo un winform en el que quiero permitir que el usuario mueva un control.Cómo permitir al usuario mover un control en el formulario

El control es (por ahora) una línea vertical: etiqueta con la frontera y una anchura de 1.

El contexto no es muy importante, pero lo voy a dar a usted de todos modos. Tengo antecedentes con algunos gráficos y me gustaría que el usuario pueda deslizar una guía sobre los gráficos. Los gráficos se hacen con la biblioteca NPlots. Se ve algo como esto: http://www.ibme.de/pictures/xtm-window-graphic-ramp-signals.png

Si puedo descubrir cómo el usuario puede hacer clic y arrastrar el control de etiqueta/línea alrededor de la pantalla, puedo resolver mi problema de guía. Por favor ayuda.

Respuesta

8

El código para esto puede ser un poco complejo, pero esencialmente tendrá que capturar los eventos MouseDown, MouseMove y MouseUp en su formulario. Algo como esto:

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

Gracias! Funciona perfectamente. – Roast

3

En WinForms, puede controlar los eventos MouseDown, MouseMove y MouseUp de un control. En MouseDown, establezca un bit o referencia diciéndole a su formulario en qué control se hizo clic, y capture las X e Y del mouse de MouseEventArgs. En MouseMove, si se establece un control, ajuste su X e Y por la diferencia entre su última captura X e Y y las coordenadas actuales. En MouseUp, libera el control.

Me gustaría configurar un "modo de edición" para esto; cuando el usuario ingresa a este modo, los controladores de eventos actuales de los controles de su formulario deben separarse y los manejadores de movimiento deben estar adjuntos. Si desea conservar o revertir estos cambios (como si estuviera creando un diseñador de formularios personalizado que su cliente pueda usar para personalizar los diseños de ventanas), también deberá poder tomar una especie de instantánea de los diseños de antes y después de los controles.

0

Aquí es un método de extensión que se puede utilizar para cualquier control. Utiliza Rx y se basa en la publicación A Brief Introduction to the Reactive Extensions for .NET, Rx y muestra de 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)); 
    } 
} 

Uso:

ButtonButton1 = new Button();

button1.EnableDragging();

0

Bueno, con toda honestidad hay una manera más simple en la que inicializas una variable booleana global llamada lo que quieras, en este caso, isMouseClicked. En su control, desea permitir el arrastre vaya al evento del mouse hacia abajo,

Asegúrese de que estos eventos sean sus eventos de control, no su evento de formularios.

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

A continuación, vaya a su desplazamiento del ratón

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

En el ratón hacia arriba asegúrese de establecer su isMouseClicked a false;

Cuestiones relacionadas