Usando el evento DoubleClick en una clase heredada de ListView

Tengo una sola clase llamada MyClass que hereda de ListView... así que básicamente es una vista de lista y puedo usarla en un formulario, etc. He anulado los eventos de arrastrar y soltar para esta clase, así que ahora si pongo dos de estos controles en un formulario y arrastre elementos de uno a otro, lo hará bien. Mi problema es con DoubleClick. ¿Cómo puedo implementar DoubleClick() en esta clase? entonces, cuando luego coloque dos de estos controles en un formulario y haga doble clic en un elemento de uno de ellos, lo moverá al otro control... ¿Es posible?

preguntado el 22 de mayo de 12 a las 18:05

¿Has probado el evento MouseDoubleClick? Solo preguntaba... A menos que esté preguntando cómo puede asociar los dos entre sí. -

@K'Leg: No señor, no he pensado en MouseDblCLick y en cómo puede ayudarme, más aclaraciones al respecto serán geniales. Gracias. -

Ok, solo estaba bromeando, pero ahora me pregunto... de todos modos, escribí un ejemplo completo para usted a continuación, que asocia dos copias del mismo control a sí mismo e implementa el doble clic:

3 Respuestas

Tenía curiosidad de cómo se podía lograr esto, así que lo probé. Creé un nuevo proyecto de formularios de Windows y creé myClass: ListView (vea el código a continuación). Luego agregué dos controles al formulario y los vinculé usando la propiedad hermana (que realmente no escribí como una propiedad)

Agregué 1 elemento a myClass1 y 2 elementos a myClass2. Cuando hago doble clic en cualquiera de ellos, se mueven a la otra vista de lista.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        myClass1.sister = myClass2;
        myClass2.sister = myClass1;
    }
}

public class myClass : ListView
{
    //This is where we will store the information about the sister Control
    private myClass _sister;
    //**EDIT**  I changed sister into a property and now it is selectable
    //from the designer.
    public myClass sister { get { return _sister; } set { _sister = value; } }

    public myClass()
    {
    }
    //here is where we override the OnDoubleCLick Event
    protected override void OnDoubleClick(EventArgs e)
    {
        //Make sure this control has a sister 
        if (sister != null)
        {
            //add a temporary storage location for the selected Item
            ListViewItem item = this.SelectedItems[0];
            //Remove the Item from the clicked List
            this.Items.Remove(item);
            //Add the Item to the sister List
            ((myClass)sister).Items.Add(item);
        }
        base.OnDoubleClick(e);
    }

}

contestado el 22 de mayo de 12 a las 19:05

Muchas gracias. Abriré una nueva aplicación y probaré tu código. - Bohn

Esta es una buena solución, aunque prefiero usar HitTest en lugar de SelectedItems. Descubrí que, en algunos casos (no en la vista de lista, sino en la cuadrícula de datos), el evento del mouse se activó antes de la actualización de la selección que proporciona el elemento seleccionado anterior. Y también establecería el tipo de hermana en ListView en lugar de control. O utilice una interfaz. - Samy Arous

Yo no diría profesional :) Solo necesita estar seguro de que la hermana tiene un elemento de propiedad. Si la hermana es un control, no puede estar seguro de eso y tendrá que verificar cada vez (¿reflexión?). El uso de ListView resolverá el problema, pero solo podrá transferir elementos de ListView a otro ListView. Usando una interfaz, podrá hacer la transferencia a cualquier control que implemente esta interfaz. Esto puede ser una vista de lista, una vista de árbol de cualquier tipo de contenedor. En realidad, en lugar de elementos, simplemente haría que la interfaz tuviera 1 AddItem de función única para una mayor generidad. - Samy Arous

Edité mi respuesta ligeramente para evitar que el diseñador la hermanara con un control diferente, ahora solo debería poder hermanarse con un objeto myClass: Gris general

De acuerdo, listview habría estado bien. - Gris general

Esto es posible accediendo Parent en el control, y moviéndose a través de él Controls:

var allMyClasses = this.Parent.Controls.OfType<MyClass>().ToList();

int index = allMyClasses.IndexOf(this);

MyClass target = null;
if (index == allMyClasses.Count - 1)
{
    target = allMyClasses[0];
}
else if (allMyClasses.Count != 0)
{
    target = allMyClasses[index + 1];
}

No estoy 100% seguro del código exacto (no probado), pero la técnica general debería funcionar lo suficientemente bien. Usted, por supuesto, querrá verificaciones nulas en Parent, y deberá incluir estos detalles en MouseDoubleClick, pero no debería funcionar.

contestado el 22 de mayo de 12 a las 18:05

Hmmm. Sí. Todavía no lo probé, pero su idea es recorrer los controles en el formulario del host y encontrar el origen y el destino, y luego el resto del problema es fácil, mueva un elemento de este a ese. - Bohn

Sí, ese es el resumen, tiene el beneficio de que no tiene que configurar manualmente el control 'Hermana': chris pfohl

¿Has probado esto ?:

private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
        ListView source = sender as ListView;
        ListViewItem item =  source.HitTest(e.Location).Item;
        if (item != null)
        {
            MessageBox.Show("Item " + item.Text + " was double clicked on " + source.Name );
        }
    }

El remitente le dirá en qué vista de lista se hizo doble clic y, dado que ya implementó la función de arrastrar y soltar, supongo que debería poder implementar la transferencia de la misma manera.

contestado el 22 de mayo de 12 a las 18:05

Ok, obtenemos el "elemento", pero ¿cómo sabemos cuál es el origen y el destino para mover este elemento? - Bohn

La variable del remitente le dará la fuente. El objetivo se puede definir usando un simple interruptor, dependiendo de la lógica de su aplicación. - Samy Arous

¡ah! buena decisión del remitente, está bien para la primera parte, ¿qué tal la parte más difícil? la parte que menciona "El objetivo se puede definir usando un interruptor simple, dependiendo de la lógica de su aplicación". por favor explique esto un poco más. Gracias Señor. - Bohn

Bueno, si tiene 2 vistas de lista, digamos lv1, lv2. un simple if(source == lv1) dest = lv2; más destino = lv1; debería hacer. La definición de qué vista de lista usar dada la fuente depende de sus especificaciones. si explicas tu lógica, te daré una mejor solución. - Samy Arous

Luego, agregue un campo en la clase personalizada en la que le diga a qué destino debe transferir el elemento :) - Samy Arous

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.