[C#] Drag & Drop Listview

Pagina: 1
Acties:

  • Sebazztiaan
  • Registratie: Februari 2002
  • Laatst online: 21-04 16:53
Tweakers,

Ik zit met een probleem, op zich hoeft het geen groot probleem te zijn, maar ik zit met een issue in C#, het draggen en droppen.

Ik ben voor mezelf een FTP client aan het maken, zie het plaatje hieronder:

Afbeeldingslocatie: http://www.musicpalace.nl/fotosebas/sshotSunburstFTPsmall.jpg'

Nu wil ik dus drag en drop implementeren van de listview aan de linkerkant, naar de listview aan de rechterkant. Volgens de MSDN begint een drag en drop operatie met een MOUSEDOWN. Dit heb ik dan ook geimplemteerd, en de andere dingen die noodzakelijk zijn.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void flvOnMouseDown(object sender, MouseEventArgs mea)
{
    DragDropEffects dde = DoDragDrop("listviewItemWaarde", DragDropEffects.Copy);
}

private void flvOnDragDrop(object sender, DragEventArgs dea)
{
        //copy the shit
}

private void flvOnDragOver(object sender, DragEventArgs dea)
{
    dea.Effect = DragDropEffects.Copy;
}


Maar nu heb ik dus mijn probleem. De listview kent een OnItemActivate, om te kunnen dubbelklikken op de mapjes.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
protected override void OnItemActivate(EventArgs ea)
{
    base.OnItemActivate(ea);

    foreach(ListViewItem lvi in SelectedItems)
    {
        try
        {
            if(lvi.Text == "..")
            {
                strDirectory = strDirectory.Substring(0, strDirectory.LastIndexOf("\\"));
                this.ShowFiles(strDirectory);
            }
                    
            if(lvi.Tag.ToString() == "FILE")
            {
                return;
            }
                    
            this.ShowFiles(lvi.Tag.ToString());
        }
        catch
        {
            continue;
        }
    }
}


Maar nu conflicteerd dit dus. De oplossing die ik zoek is een dubbelklik op een map-item -> de directory wordt geopend, en een klik->sleep moet de drag&drop worden geactiveerd.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 01-05 19:09

pjvandesande

GC.Collect(head);

Je kan toch een flag setten dat de mouse down is en daarna bij het mousemove event kijken of deze flag geset is. Zoja, dan een DoDragDrop uitvoeren.

toevoegin:
Wat een strakke controls, welke gebruik je als ik vragen mag of heb je ze zelf in elkaar gedrukt? O+

[ Voor 33% gewijzigd door pjvandesande op 06-12-2004 13:16 . Reden: Zie toevoegin :+ ]


  • Sebazztiaan
  • Registratie: Februari 2002
  • Laatst online: 21-04 16:53
Dat klopt, dat kan zeker, maar als ik dus nu 1 keer op mijn muisknop klik dan veranderd dus meteen de muiscursor in het drag en drop icoon, en kan ik alsnog niet dubbelklikken\

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void flvOnDragDrop(object sender, DragEventArgs dea)
{
    mouseDown = false;
}

private void flvOnDragOver(object sender, DragEventArgs dea)
{
    dea.Effect = DragDropEffects.Copy;
}

private void flvOnMouseDown(object sender, MouseEventArgs mea)
{
    this.mouseDown = true;
}

private void flvOnMouseMove(object sender, MouseEventArgs e)
{
    if(mouseDown)
    {
        DragDropEffects dde = DoDragDrop("listviewItemWaarde", DragDropEffects.Copy);
    }
}


Btw, het menu en de toolbar is van Sandbar, die is ech cool, en gratis :), de rest van de controls zijn van mijzelf.

[ Voor 10% gewijzigd door Sebazztiaan op 06-12-2004 13:22 ]


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 01-05 19:09

pjvandesande

GC.Collect(head);

Je kan de pixels tellen hoeveel afstand er tussen zit en pas bij een mousemove van meer dan bv. 5pixels een DoDragDrop uitvoeren, maar ik vind dit persoonlijk ronduit ransig.

Bij een dubbelklik heb je toch geen mousemove? De workaround die ik net noem heb ik al vaker gezien. Ook heb ik het wel is gezien met het aantal miliseconden bekijken hoelang de mouse down is en pas na bv. 5ms de DoDragDrop uitvoeren.

Ik ga is kijken naar de Sandbar! :)

  • Sebazztiaan
  • Registratie: Februari 2002
  • Laatst online: 21-04 16:53
Ik heb het toch op die ranzige manier gedaan

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void flvOnMouseMove(object sender, MouseEventArgs mea)
{
    bool move = false;
    
    if((mea.X < this.x - 15)  ||  (mea.X > this.x + 15) || (mea.Y < this.y - 15) || (mea.Y > this.y + 15))
    {
        move = true;
    }

    if(mouseDown && move && (flv.SelectedItems.Count != 0))
    {
        DragDropEffects dde = DoDragDrop("listviewItemWaarde", DragDropEffects.Copy);
    }
}


oh ja, die sandbar kan je downloaden op www.divil.co.uk

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 01-05 19:09

pjvandesande

GC.Collect(head);

Je zit nu alleen nog met het probleem dat als je heel dicht langs de kant begint met slepen. Want dan kun je de 15px niet halen. Maarja, dit zal niet vaak voorkomen lijkt mij.

offtopic:
Bedankt voor de Sandbar!
:>

Verwijderd

Ik had ook te maken met deze issue, ik heb er een (denk ik) aardige oplossing voor gevonden. Je kunt binnen een mousedown void zien hoeveel keer er geklikt is. Bij de eerste klik wordt de drag drop code geinitialiseerd, maar je ziet pas een andere cursor als de muis echt beweegd. Daar zie je dus niets van bij een dubbelklik. Wanneer er 2 keer geklikt is, kun je gewoon je dubbelklik-code uitvoeren zonder dat die drag-drop in de weg zit. Is nog steeds niet de ideale manier omdat nu toch de drag-drop code bij een dubbelklik geinitialiseerd wordt, maar het is wel makkelijker en degelijk.


C#:
1
2
3
4
5
6
7
8
9
10
11
private void lvItems_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{       
    if (e.Clicks == 1)
    {
        // 1 keer geklikt, drag drop initialiseren
    }
        if (e.Clicks == 2)
    {
        // 2 keer geklikt, doubleclick-code uitvoeren
    }
}

[ Voor 3% gewijzigd door Verwijderd op 15-05-2005 01:54 ]

Pagina: 1