Makale Özeti

Düğme, metin kutusu, etiket gibi bir nesneyi pencere içerisinde bir yerden başka bir yere taşımak veya bir nesne içerisinde metin gibi değerleri başka bir nesneye taşımak için .net ortamının bize sağladığı “sürükle ve bırak” özelliğini kullanırız.

Makale

dragdrop

 

Drag & Drop
(Sürükle ve Bırak)

Düğme metin kutusu etiket gibi bir nesneyi pencere içerisinde bir yerden başka bir yere taşımak veya bir nesne içerisinde metin gibi değerleri başka bir nesneye taşımak için .net ortamının bize sağladığı “sürükle ve bırak” özelliğini kullanırız. Bir nesne içerisinde değeri sürüklemek için veya sürüklenen bir değeri başka bir nesnenin kabul etmesi için bu nesnelerin “sürükle ve bırak” özelliğine izin vermeleri gerekir. Bunu sağlamak için nesnelerin AllowDrop özelliğini True olarak ayarlamak gerekir. Bu değer varsayılan olarak False ayarlanmıştır. Bu nedenle ilk olarak bu işlemin yapılması uygun olur.

Şimdi bir örnekle bu ilişkiyi uygulamaya dökelim. Örneğimizde 2 adet listbox nesnesi vardır. Soldakinde illerin listesi bulunmaktadır. Bu illerden herhangi birini sürükleyerek sağdaki listbox nesnesinin üzerine bırakacağız ve bu sürüklenen değer sağdaki listbox nesnesine eklenecek. Bunu yapmak için aşağıdaki adımları izliyoruz:

1-     Yeni bir Windows Application oluşturun.
2-     Forum üzerine iki adet Listbox nesnesi ekleyin. Ben isimlerini değiştirmeden varsayılan isimleri kullandım. Siz isterseniz değiştirebilirsiniz. Ancak verdiğiniz isimlere göre aşağıdaki kodları değiştirmeyi unutmayın.
3-     Soldaki birinci liste kutusu içerisine aşağıdaki resimde görüldüğü gibi birkaç ilimizin ismini ekleyin. Bunun için properties panelindeki Items özelliğini veya liste kutularını seçtiğinizde sağ üstte görülen küçük okla açılan “Listbox Tasks” panelini kullanabilirsiniz.

4-     Her iki liste kutusunun AllowDrop özelliğini True olarak ayarlayın.
5-     Soldaki birinci liste kutusunun olaylarını açın
6-     Mousedown olayına çift tıklayın. Bu sizi kod ekranında “listbox1_MouseDown” metoduna götürecektir.
7-     Aşağıdaki kodu metodun içine ekleyin.

private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
Point p = new Point(e.X, e.Y);
int ndx = this.listBox1.IndexFromPoint(p);
if (e.Button == MouseButtons.Left)
{
this.listBox1.DoDragDrop(this.listBox1.Items[ndx].ToString(), DragDropEffects.All);
}
}

8-     İkinci listboxun olaylarını açın ve DragOver olayına çift tıklayın. Aşağıdaki kodu bu olayın metoduna yazın.

private void listBox2_DragOver(object sender, DragEventArgs e)
{
if (e.KeyState == 1)//hiçbiri
{
e.Effect = DragDropEffects.Move;
}
}

9-     İkinci listboxun olaylarını tekrar açın ve DragDrop olayına çift tıklayın. Aşağıdaki kodu bu olayın metoduna yazın.

private void listBox2_DragDrop(object sender, DragEventArgs e)
{
this.listBox2.Items.Add(e.Data.GetData(DataFormats.Text).ToString());
}


10- Uygulamanızı çalıştırın. Soldaki listboxtan bir değeri sağdaki liste kutusuna taşıyın. Aşağıdaki gibi bir görüntü oluşacaktır.

Kodlarımızı yakından inceleyelim.

Listboxun “IndexFromPoint” metodu mouse’umuzun tıkladığı noktadaki değerin endeks numarasını bulur. Bu metot parametre olarak Point sınıfının bir örneğini veya x ve y koordinatlarını alır. Biz Point sınıfını kullandık.

“If” sorgulaması içerisinde ise tıklanan fare düğmesinin sol tuş olup olmadığı kontrol edilmektedir. Sağ tıklayarak değerlerin sürüklenmesini istemediğimiz için “if(e.Button == MouseButtons.Left)” sorgulamasını kullandık. Eğer sol tuş tıklanmışsa liste kutusunun DoDragDrop metodunu kullanarak seçilen nesneyi sürüklenen değer olarak belirledik.Bu metodun birinci parametresi sürüklenecek olan değeri, ikinci parametresi ise sürükleme efektini belirler. Bu efektler “DrogDropEffects” numaralı listesinde tanımlanmıştır. Bunlar:

public enum DragDropEffects
{
Scroll = -2147483648,
All= -2147483645,
None = 0,
Copy = 1,
Move = 2,
Link = 4,
}

Scroll: Hedef nesne içerisinde kaydırma işlemini başlatır.
All: Tüm sürükleme efektlerine izin verir.
None: Sürüklemeye izin vermez.
Copy: Seçilen değer kopyalama efekti ile taşınır.
Move: Seçilen değer taşıma efekti ile sürüklenir.
Link: Sürüklenen değer hedef nesneye bağlantı olarak eklenir.

Sağdaki listboxumuzda “DragOver” metodu kullanmamızın sevevi bir değerin, nesnenin üzerinde sürüklenince ne yapacağını belirlemektir.

If (e.KeyState == 1) satırını da sürüklene sırasında klavyedeki CTRL, SHIFT veya ALT tuşlarına basılı olup olmadığını kontrol eder. Bu değer 1 ise hiçbir tuşa basılı değil anlamına gelir.

1: hiçbiri
9: CTRL
5: SHIFT
33: ALT
13: SHIFT + CTRL
37: SHIFT + ALT
41: CTRL + ALT
45: CTRL + ALT + SHIFT

Eğer klavyedeki CTRL, SHIFT veya ALT tuşlarından herhangi birine basılı değilse, bu durumda bizim istediğimiz şart gerçekleşmekte ve sürükleme efekti olarak “move” yani taşıma seçilmektedir. Buraya aşağıdaki kodu ekleyerek CTRL ile sürükleme işlemi yapıldığında fare imlecinde kopyalama sembolü yani + sembolünün görünmesini sağlayabiliriz.

if (e.KeyState == 1)//hiçbiri
{
e.Effect = DragDropEffects.Move;
}
if (e.KeyState == 9) //CTRL
{
      e.Effect = DragDropEffects.Copy;
}

Ancak bunlar sadece efekt oluşturur. Gerçektende kopyalama veya taşıma işlemi oluşturmak istiyorsanız biraz daha kod eklemeniz gerekir. Bu örnekte bu kodları sağdaki listboxun DragDrop metoduna yazdık.

this.listBox2.Items.Add(e.Data.GetData(DataFormats.Text).ToString());

Bu satırda sürüklenen değer alınıp liste kutusuna eklenmesi sağlanmaktadır. Bunun için “DragEventsArgs” sınıfının GetData metodu kullanılmıştır. Bu metod Data nesnesine ait olup, parametre olarak değerin formatını alır. Bu formatı belirlerken “DataFormats” sınıfını kullanabilirsiniz. Bu sınıfın “static” olan özellikleri, yani formatları şunlardır:


public static readonly string Bitmap;
public static readonly string CommaSeparatedValue;
public static readonly string Dib;
public static readonly string Dif;
public static readonly string EnhancedMetafile;
public static readonly string FileDrop;
public static readonly string Html;
public static readonly string Locale;
public static readonly string MetafilePict;
public static readonly string OemText;
public static readonly string Palette;
public static readonly string PenData;
public static readonly string Riff;
public static readonly string Rtf;
public static readonly string Serializable;
public static readonly string StringFormat;
public static readonly string SymbolicLink;
public static readonly string Text;
public static readonly string Tiff;
public static readonly string UnicodeText;
public static readonly string WaveAudio;

Görüldüğü gibi bir çok biçimde veri sürüklenebilmektedir. Bunların “static” olmaları DataFormats sınıfının örneğinin oluşturulmasına gerek olmadan kullanılabilmelerini sağlar.

Umarım işe yarar ve güzel bir konu olmuştur.
Farklı makalelerde tekrar görüşmek üzere.

Yağız Gönüler
yagiz.gonuler@gmail.com