sábado, 16 de mayo de 2009

Drag And Drop en PictureBox

Este efecto es muy interesante y propio de la programación orientada a objetos, en este evento (a diferencia de los otros que solo desencadena un procedimiento, como el Click, load, Mouse Move etc) se desencadenan tres procedimientos:

Mouse Move
DragEnter
DragDrop

En ese orden.

Imaginemos que tenemos dos pictureBox de Nombre Foto1 y otro de nombre Foto2 lo primero que debemos haces es activarles el Drag And Drop, en el evento Load del formulario escribimos:

Foto1.AllowDrop=true;
Foto2.AllowDrop=true;

Cuando le den clic no va a aparecer, así que no se preocupen al respecto solo escríbanlo.

Ahí mismo declaramos una variable de tipo object llamada origenes que sea publica

object origenes;

Esta variable se utiliza para mantener la referencia al objeto de donde se está arrastrando la imagen de no ser así, solo podríamos hacer Copiar/Pegar y nó Drag And Drop, es recomendable declarar esta variable antes del constructor.

Bueno, una vez realizado esto, van a hacer copy/Paste a los procedimientos que llamaran desde los eventos del drag and drop, anteriormente mencionados:

Esto es lo que van a a asociar al evento Mouse Down de los PictureBox Foto1 y Foto2, claro solo el nombre que seria PictureBox_MouseDown

private void PictureBox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
///Objeto de origen de la imagen
PictureBox pic = (PictureBox)sender;
origenes = sender;


if (e.Button == MouseButtons.Left)
{
if (pic.Image != null)
{
pic.DoDragDrop(pic.Image, DragDropEffects.Move);
}
}
}

-------------------------------------------------------------------------------------

Esto en el Drag Enter de los dos Picture Box llamas PictureBox_DragEnter

private void PictureBox_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{

if (e.Data.GetDataPresent(DataFormats.Bitmap))
{
e.Effect = DragDropEffects.Move;
}
else
{
e.Effect = DragDropEffects.None;
}
}

-------------------------------------------------------------------------------------
Y por ultimo en el DragDrop asociamos esto:

private void PictureBox_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
PictureBox pic = (PictureBox)sender;
PictureBox org = (PictureBox)origenes;

if (pic.Name != org.Name)
{

pic.Image = (Bitmap)e.Data.GetData(DataFormats.Bitmap);
org.Image = null;

}


}

Una importante observación, esto se copia y pega dentro del formulario, no dentro de ningún evento y luego a los dos objetos se les asocia en cada evento los nombres de los procedimientos Ejemplo

En los eventos (Que están en el símbolo de rayito en la ventana de propiedadas que aparece a la derecha de la ventana) buscamos el evento MouseMove y sin darle doble click en el espacio escribimos PictureBox_MouseDown y damos Enter, igual con los otros, una vez terminado, ejetutamos el formulario y listo.

52 comentarios:

  1. mmm profe... eso no es todo el codigo q elaboramos ahora verdad??.....

    ResponderEliminar
  2. POR FIN LOGRE ENTENDERLE MAS O MENOS A LA CLASE NO DEL TODO PERO ALLI VOY FELIZ NOCHE

    ResponderEliminar
  3. gracias profe por subir esto de mucha ayuda para muchas personas jajajaja bueno yo le entiendo no a la perfeccion pero me defiendo jajjaja gracias por el codigo

    ResponderEliminar
  4. Rosseling:
    Esto es lo esencial para hacer D&D a picturebox, no necesariamente para el juego de ajedrez que estamos desarrollando, prueba copy/paste del codigo sigue las intrucciones y veras que funcionas, bueno se supone que funciona sinó me avisas

    Karla e IVAN:
    Me alegra que le entiendan mejor y siempre son bienvenidos en mis clases.

    ResponderEliminar
  5. bueno eh entendido un poco mejor ya analizando aqui en el blog... muchas gracias profe... uste es la mera motherboard!

    ResponderEliminar
  6. eii graxx prof. porla info buen aporte todavia no le agarro la honda pero voy a dar lo mejor de mi para enterderle

    ResponderEliminar
  7. Ranchz jejejejje: gracias, me alegra que le entienda mejor

    Victoravelar 5:
    Gracias Victor, pero estas participaciones no valen para sumar puntos, solo son "relleno" tiene que aportar algo a la clase o hacer alguna pregunta "importante" (no como que hora es? o tenemos clases mañana), de no ser así no tienen ningún valor académico

    Saludos

    ResponderEliminar
  8. prof. me puede mandar el C# al correo para no esperar hasta mañana

    ResponderEliminar
  9. mira victor talves te sirve este link no lo e provado pero te lo mado talves te sirve http://www.microsoft.com/express/vcsharp/#webInstall copeas y pegas en una nueva ventana o pestaña le das donde dice Download en verde creo y guardas el archivo

    ResponderEliminar
  10. ok ivan graxx lo voy a provar aver

    ResponderEliminar
  11. Prof. los temas del son los que ban a entrar en examen.

    ResponderEliminar
  12. pucha wizar nunca se conecto lo quedemos esperando ta bueno pues

    ResponderEliminar
  13. profesor verdad que el formato de la imagenes de los programas png

    ResponderEliminar
  14. hacerca de la tarea de investigacion es su correo o lo llevamos en memoria

    ResponderEliminar
  15. esa mera oscar :) bienvenido al clan UTH :)

    ResponderEliminar
  16. Oscar, Danny que honda como van con el proyecto

    ResponderEliminar
  17. profe tengo muchas preguntas
    una de ellas es
    PictureBox pic = (PictureBox)sender;
    origenes = sender;

    pork el PictureBox va con el sender?
    entiendo de k origenes va a ser igual a sender

    ResponderEliminar
  18. Wizar hacerka sobre el programa k me envio ese de
    "treevie" ese programa esta fuera de mi orbita :S no esta dentro de mis konocimientos, la verdad no me ayuda para lo poko k se )=

    ResponderEliminar
  19. otra de mis interrogantes es pork si koloko un objeto sobre otro objeto este se borra, donde tengo k programar para k esto no suceda??
    y k programacion tengo k aplikar..??
    solo se k tendria k utilizar un IF

    ResponderEliminar
  20. profe tengo esto en mi tablero pero cuando lo corro no puedo hacer nada ni mover piezas

    public partial class Form1 : Form
    {
    int x_o, y_o;
    int x_d, y_d;
    string origen, destino;
    object origenes;
    string[,] datos = new string[8, 8];
    const byte CtrlMask = 8;
    public Form1()

    {
    InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    A1.AllowDrop = true;
    A2.AllowDrop = true;
    A3.AllowDrop = true;
    A4.AllowDrop = true;
    A5.AllowDrop = true;
    A6.AllowDrop = true;
    A7.AllowDrop = true;
    A8.AllowDrop = true;

    A9.AllowDrop = true;
    A10.AllowDrop = true;
    A11.AllowDrop = true;
    A12.AllowDrop = true;
    A13.AllowDrop = true;
    A14.AllowDrop = true;
    A15.AllowDrop = true;
    A16.AllowDrop = true;
    A17.AllowDrop = true;
    A18.AllowDrop = true;
    A19.AllowDrop = true;
    A20.AllowDrop = true;
    A21.AllowDrop = true;
    A22.AllowDrop = true;
    A23.AllowDrop = true;

    A24.AllowDrop = true;
    A25.AllowDrop = true;
    A26.AllowDrop = true;
    A27.AllowDrop = true;
    A28.AllowDrop = true;
    A29.AllowDrop = true;
    A30.AllowDrop = true;
    A31.AllowDrop = true;
    A32.AllowDrop = true;
    A33.AllowDrop = true;
    A34.AllowDrop = true;
    A35.AllowDrop = true;
    A36.AllowDrop = true;
    ...


    }

    private void picturebox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    {
    if (e.Button == MouseButtons.Left)
    {
    PictureBox pic = (PictureBox)sender;
    if (pic.Image != null)
    { pic.DoDragDrop(pic.Image, DragDropEffects.Move | DragDropEffects.Copy); }

    }
    }
    private void picturebox_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
    {
    if (e.Data.GetDataPresentDataFormats.Bitmap))
    {
    e.Effect =DragDropEffects.Move;
    }
    else
    {
    e.Effect =DragDropEffects.None;
    }
    }
    private void picturebox_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
    {
    PictureBox pic = (PictureBox)sender;
    pic.Image = (Bitmap)e.Data.GetData(DataFormats.Bitmap);
    if ((e.KeyState & CtrlMask) != CtrlMask)
    {
    #region patito
    switch (pic.Name)
    {
    case "A1":
    A2.Image = null;
    A3.Image = null;
    A4.Image = null;
    A5.Image = null;
    A6.Image = null;
    A7.Image = null;
    A8.Image = null;
    A9.Image = null;
    A10.Image = null;
    A11.Image = null;
    A12.Image = null;
    A13.Image = null;
    A14.Image = null;
    A15.Image = null;
    A16.Image = null;
    break;
    case "A2":
    A1.Image = null;
    ...
    # endregion

    ResponderEliminar
  21. profe necesito la programacion sobre validar las posiciones para ganar no entiendo komo serian
    por ejemplo en un X-0

    If [0,4,8] = PictureBox
    messegeBox = "La X ha Ganado"

    esta bien asi o ando perdido?

    ResponderEliminar
  22. perdon el ejemplo seria

    If XO =[0,4,8]

    como seria para poner si estas posiciones tienen
    un objeto dentro??

    ResponderEliminar
  23. una consulta en caso ke me saliera hacer el damero pero el problema es ke estoy buscando las piezas y no me salen de ninguna manera solo me sale un damero completo o lo vamos a trabajar con peones????

    ResponderEliminar
  24. profe probe de todas las formas de mis konocimientos, y no bastan tengo k saber mas, tengo muchas preguntas

    1 como saber kuando una posicion tiene una imagen y kuando no

    2 komo hacer k una imagen no se ponga sobre otra imagen

    3 komo puedo valir la posicion del gane en X0 su se trata de 3 posiciones

    4 komo puedo programar el turno de los players

    son preguntas k necesito la respuesta para seguir adelante profe

    se lo agradeseria muchoo si me ayuda kon mis interrogantes..!!

    ResponderEliminar
  25. jenn el switch qque tenes de pic name nbo va debido a que si igualas todas las imagenes a null estas se borrarian al mover una pieza

    ResponderEliminar
  26. Oscar la investigacion la presentas el lunes en tu memoria

    ResponderEliminar
  27. las imagenes son png pero tmbien tienen que tener transparencia o algo asi

    ResponderEliminar
  28. josue sender es la variable tipo object que declaras anteriormente solamente la igualas al la imagen del picturebox creo loko

    ResponderEliminar
  29. josue pones el nombre del picturebox enves de [0,4,8] creo que asi seria loko

    ResponderEliminar
  30. jenn y acordate de crear la clase con las validaciones y todo lo demas :)

    ResponderEliminar
  31. saber kuando una posicion tiene una imagen y kuando no creo que con un if seria si f3,c4 es igual a una de las tdn o cualkier otra de las piesas que tenes en tu arreglo bidi que diga movimiento invalido y no mueva la pieza de lo contrario que la mueva creo que asi seria

    ResponderEliminar
  32. el turno de los players con el color al igual que el ajedrez loko

    ResponderEliminar
  33. profe tngo una gran pregunta, ¿como hacer validar los movimientos? en esa parte no le entiendo me gustaria k subiera el codigo...

    ResponderEliminar
  34. profe a la validacion de movimiento de las piezas me confundo algo o mejor dicho no le entiendo " if (((f_d == f_o + 1) || (f_d == f_o + 2)) && (c_o == c_d) && (datos[f_d,c_o]=="-"))
    return 1;" siento fd= fila destino y fo=fila de origen la verdad no le entiendo

    ResponderEliminar
  35. Buen dia profe.. ayer me explico como hacer para capturar las piezas.. osea que cuando tenga la oportunidad de "comer" se desaparezca la pieza que comio..! aqui no encontre nada sobre eso..! eso no lo pude hacer en el examen por que no tenia ni idea de como hacerlo.... ahh y lo de validar los movimientos.. no le entiendoo.. no se como hacer por que ya para mañana es eso y estoy cabal ahi..!! le agradeceria una respuesta rapida.. o su ayuda.! porfavor.!!
    nos vemos al rato.!

    ResponderEliminar
  36. Jcrus:

    PAra ganar en el X-O tenias que validar

    if (tablero[0,0]=="x"&& tablero[0,1]=="x" && tablero[0,2]="x")
    MessageBox.Show("Las X Ganan");

    Tienes que validar las otras dos filas y las tres columnas y por ultimo las dos diagonales

    Saludos

    ResponderEliminar
  37. JCRUZ:

    No puede evalugar las imagenes, para eso necesita el arreglo por cada movimiento, reflejar el arreglo que mueva a la casilla correspondiendo, con lo de el turno del player, y lo demas, verifique el ejemplo del Tablero de Ajedrez

    Saludos, siga intentando

    ResponderEliminar
  38. ke_guevara:
    De la misma forma que validamos los peones, asi validamos los otros movimientos, primero debe sasber como mueven cada uno de estos

    voy a ver si hago el del caballo y lo subo

    Saludos

    ResponderEliminar
  39. Oscar

    El peon mueve uno o dos posicones par en adelante en el caso de ser blanco y para atras en el caso de ser negro, pero en el arreglo el movimiento se invierte porque los indices son de menor a mayor, por es razon los movimientos del peon son fila +1 y la columna es la misma, a menos que capture, seria fila +1 y columa+1 o columna -1 porque puede capturar tanto a la izqjuierda de su pos o la derecha

    saludos

    ResponderEliminar
  40. Marito:

    Cuando CAPTURAS, una pieza, solo ocupas el espacio de esta, tanto en el tablero como en el arreglo

    algo mas especifico??

    saludos

    ResponderEliminar
  41. Buenas, espero que puedas ayudarme. Estoy intentando entender esto del drag&drop, y aunque con tu ejercicio pude modificarlo para poner 4 fotos he intercambiarlas de lugar, sigo sin entender mucho la "teoria subyacente" del tema. Podrias darme algun link donde pueda yo leer mas sobre el tema? Eso por un lado y por otro, de que manera se puede hacer que al arrastrar el pictureBox en lugar de que el puntero cambie el icono muestre una copia de la imagen? Desde ya muy agradecido, al menos ya se como puedo hacer lo que quiero hacer gracias a tu ejemplo.

    ResponderEliminar
  42. Hola LHAN:
    Con respecto a la teoría esta difícil porque el ejercicio original lo bajé de los ejemplos de microsoft.

    Con lo otro, yo también me estoy haciendo esa misma pregunta porque quiero hacer un solitario, ya lo hice una vez, hace tiempo pero sin drag and drop, pero creo que saldría haciendo un DND desde controles en el form, que podas mover todo el control picture box y que de forma mágica (porque por los momentos no se) se copiara en el otro...

    En el apartado para descargar creo que tengo subido el ejemplo del ajdrez que estoy desarrollando con mis alumnos, ahi lo vez hay para lo del drag and drop

    Espero te sirva, si consigo una teoria convincente la posteo

    Saludos

    ResponderEliminar
  43. Hola de nuevo, primero que nada, no pude encontrar el apartado "descargar" jejeje. Y segundo, estuve intentando un par de cosas y pude mover el picturebox mientras hacia el dragdrop por medio del evento GiveFeedBack, el problema es que solo funciona para los primeros picturebox, segun el orden en que fueron creados, pues:
    Si inicias un DoDragDrop y mueves el control junto con el mouse esto provoca un constante DragOver.
    Si mueves un control, y debido al orden de creacion, este queda (o se ve) debajo del "control destino", se lanza un evento DragEnter.
    Pero nunca se lanzara el evento DragEnter si el control que mueves no se posicion por debajo del "control destino".
    Finalmente lo que funciona se ve mal (se ve feo) ya que el que se mueve queda detras del destino.
    Lo ideal seria remover el control de formulario y volverlo a poner para que quede ensima, pero no ocurria jamas un evento DragEnter. Deshabilitar AllowDrop para el control no permite "transpasar" el control con el mouse.
    Finalmente la solucion que se me ocurre (muy enroscada a mi gusto) es que despues de remover y volver a agregar el control que se va a mover, seria crea por cada uno de los controles con los que se puede intercambiar un control transparente ensima. No lo he probado y ahora que lo pienso no creo que funcionaria, pues la transparencia creo que no produciria un evento DragEnter, ya que cuando use un formulario con transparencia sin barra y necesitaba moverlo, hacer click en la parte transparente era hacer click en lo que estuviera debajo (normalmente el escritorio). Asi que si se te ocurre alguna solucion, agradecidisimo.

    ResponderEliminar
  44. Mi amigo Lhan
    En el mes de MArzo dice
    Ejercicios Resueltos de C#
    Ahi encuentras tambien para descargar

    No entendí mucho tu teoria pero voy a ver si este fin de semana trabajo en eso y vemos que sacamos

    Saludos y estamos en contacto

    Tus aportes también son bienvenidos

    ResponderEliminar
  45. Ajedrez

    Bueno posteo esta pequeña respuesta a este problema, creo k no solo yo lo he tenido, bueno se refiere al codigo que el profesor puso arriba, cuando se le da copy paste a las funciones globales y al momento de ejecutarlas tira este error: http://i44.tinypic.com/29blg8n.jpg el problema se debe a que la funcion Validar_posicion_peon() dentro de los parentesis no le mandas los argumentos correctamente, puede ser que esta declarado con 5 argumentos y le mandas 6, Imaginemonos que tenemos una funcion declarada asi:

    public int patito(int x, int y, int z)
    {
    int total;
    total=x+y+z;

    return total;

    }
    como pueden ver, la funcion se llama patito y recibe 3 argumento si?? y los retorna sumados

    Ahora bien si al momento de llamarla desde un formulario la llamamos asi:

    Funciones_Globales P=new Funciones_Globales();

    Int valor_total;

    valor_total=P.patito(3,29,5,6);

    Como observas, al momento de invocarlo le mandamos mas de los argumentos que el espera, por esa razón genera un error...

    espero haberles ayudado, yo tambien tube este problemita.
    -creditos: The Wizard

    saludos

    ResponderEliminar
  46. pregunta:

    por que no hacer el drag and drop solo con javascript. para que hacerlo ir y venir al servidor, para hacer algo que en javascript es relativamente facil.

    --
    Atte.
    Victor Hugo Saavedra.
    http://vhspiceros.blogspot.com

    ResponderEliminar
  47. Hola Victor
    De que servidor esas hablando???
    La aplicacion es Winform.
    Saludos

    ResponderEliminar
  48. entonces no he dicho nada :(.


    --
    Atte.
    Victor Hugo Saavedra
    http://vhspiceros.blogspot.com

    ResponderEliminar
  49. Muchisimas gracias por el ejemplo de drag and drop... estaba perdidísima y no sabia como usarlo =)

    Seguiré este blog!

    Saludos desde España1 ^^

    ResponderEliminar
  50. Hola Fany, me alegra que te haya servido, si ocupas mas ayuda, mandame un correo a elvin.castellanos@gmail.com

    Saludos desde Honduras

    ResponderEliminar