Wie een Windowsapplicatie schrijft zal op sommige plaatsen de gebruiker de gelegenheid bieden om de interface te verlevendigen via Drag-and-Drop. Controls hebben een methode om een Dragactie te starten, namelijk DoDragDrop. Bij sommige controls is het bovendien heel eenvoudig om te zien of de gebruiker een Dragactie wil starten. Een TreeView bijvoorbeeld heeft daarvoor een ItemDrag event. Dit vertelt u direct dat een Dragactie gewenst is. Ook een ListView biedt deze mogelijkheid. Bij deze controls hoeft u dus niet te werken met de events van de muis.
Maar lang niet elke control biedt deze mogelijkheid. Een ListBox, bijvoorbeeld, heeft geen ItemDrag methode. Hoe kunt u nu weten of de gebruiker een item wenst te verslepen? Simpelweg het MouseDown event afvangen werkt niet echt goed, want bij elke muisklik begint dan direct een sleepactie en dat werkt heel onplezierig.
Mousedown is geen drag, dan moet de muis ook verschoven zijn
Voor het goed starten van een Drag moet u weten hoe Windows dit precies definieert. Een MouseDown is nog niet direct het teken voor het beginnen van een Drag. Daarvoor moet de muis vervolgens ingedrukt worden gehouden en een paar pixels worden verschoven. Hoever precies? Dat nu staat in de Registry. Er is een rechthoekje gedefinieerd onder HKEY_CURRENT_USER\Control Panel\Desktop. Daarstaan twee entries, namelijk DragHeight en DragWidth. Standaard staan deze twee waarden op 4 ingesteld, maar de gebruiker kan dit veranderen. Weliswaar biedt Windows zelf via het Control Panel er geen standaardknoppen voor, maar een gebruiker kan zelf aan de gang gaan met RegEdit en met een tooltje als TweakUI is het nog eenvoudiger.
Voor het starten van een Dragactie moet nu eerst het MouseDown event van de ListBox worden afgevangen. Definieer op het formuleer twee variabelen, als volgt:
private bool isdragstart = false;
private Point dragstartposition;
De code onder MouseDown registreert een mogelijke Drag-actie en tevens de beginpositie:
isdragstart = true;
dragstartposition = e.Location;
Als de gebruiker de muis loslaat voordat een Dragactie is gestart moet er niets worden gedaan. Dus onder het MouseUp event van de ListBox zet u deze code:
Nu komt het MouseMove event aan de beurt. U moet dus eerst controleren of de muis al buiten het gebied is gekomen dat in het Control Panel is vastgelegd als de minimale zone voor Dragging. Dit doet u als volgt:
if ( isdragstart )
{
if( Math.Abs(e.Location.X - dragstartposition.X) >
SystemInformation.DragSize.Width / 2
|| Math.Abs(e.Location.Y - dragstartposition.Y) >
SystemInformation.DragSize.Height / 2)
{
isdragstart = false;
// perform the drag
}
}
U kunt nu de data die u bij het verslepen wilt verplaatsen gaan toevoegen. Meer hierover leest u in deel twee.