C# ile Drag & Drop
Yeni bir makaleden herkese merhabalar,
Bu makalemizde çok sık sorulan ve bence kullanıcının arayüze alışması, Düşük bilgisayar bilgisi olan kullanıcıların arayüze kısa sürede adapte olabilmesi açısından çok önemli bir nokta teşkil eden Drag & Drop konusunu çok fazla karıştırmadan basitçe C# ile ele alacağız.
Unutmayın ki bir yazılım geliştirici olarak yazılımınıza odaklanmak haricinde birkaç adım sonrasını da gözlemlemek zorundasınız. Bunlara tasviri örnekler vermek gerekirse ürettiğiniz bir yazılımın üretim süreci sonunda karşılaşacaklarınızı önceden belirlemeli ve yazılımınızı bu değişken durumlara uyarlı hale getirmeli hatta uyarlı şekilde geliştirmelisiniz. Bu değişken noktalardan biride yazılımın kullanıcı bazlı eğitim sürecidir. Her ne kadar siz yazılımınızı üretirken çok fazla gözünüze gözükmese de büyük çaplı bir uygulama için binlerce dolar eğitim masrafının harcandığını ve eğitim süreci içerisinde sizin uygulamanıza rakip birçok yazılımın piyasaya çıktığını ve aynı zamanda bu rakip yazılımlar sizin programınızdan çok daha beceriksiz olsa bile kullanıcının kullanım kolaylığı nedeniyle bu rakip yazılımları tercih edebilme olasılığı her zaman mevcuttur.
Bu konuda kişisel bir örnek vermek isterim… Cep telefonu olarak benim tercihim hep X’den yana olmuştur ve bence diğer telefonlara nazaran çok daha komplike bir yapıya, çok daha işlevsel özelliklere sahip bir telefon olmuştur benim için. Ancak Türkiye’de ve dünyada bu konuda pazarın çoğunluğuna sahip firmanın Y olduğunu görmekteyiz. 10 yıl öncesine dönecek olursak. Cep telefonuyla ilk tanışmalarımızda insanların tercihi hep Y’den yanaydı bunun sebebi o günlerden bu yana çok açıktı. “Kullanım kolaylığı”…
Sanırım basit bir konu için çok fazla konuştuk. Ama bu makalede anlatacaklarımın önemsiz olarak gözlemlesek de ne kadar önemli olduğuna dikkatinizi çekmek istedim.
Artık başlayalım;
Drag & Drop yani türkçesiyle Sürükle ve Bırak biraz açacak olursak bir nesnenin içindeki objeyi alıp içeriğine uygun başka bir nesneye taşımak veya kopyasını oluşturmak olarak özetleyebiliriz.
Drag & Drop olayının esasında kısmen basit bir algoritmik yapısı olduğunu söyleyebiliriz. Bu olayı şematik olarak yansıtmak isterim.
(a) Obje seçilir ve sürüklenmeye hazırlanır > (b) İçeriği aktarılacak olan kontrole yöneltilir > (c) Seçili nesne aktarılmak istenen kontrolün üzerine bırakılır.
Bu basit şematik gösterimde a,b,c olarak nitelendirdiğim şeylerin hepsi bir olay ve bir objenin taşınması bu olayların zorunlu olarak gerçekleşmesi ve bu olayların oluştuğu andaki izinlerin kontrolleri ile meydana gelir.
Şimdi bu şematik anlatımımızı programatik öğelere döküp açıklamaya çalışayim.
Öncelikle bu makalede yapacağımız örneği biraz açıklayim. Formumuza yerleştirdiğimiz iki adet listbox kontolündeki objelerden birini alıp diğerine taşıyacağız. Başta da belirttiğim gibi konuyu basitçe ele alıyorum ancak Drag & Drop olayının en kullanışlı yöntemlerinden birinin Database üzerinde işlev gerçekleştirmek olduğunu unutmayın.
Örneğimizin görsel görüntüsü bu şekilde… Şimdi biz listBox1 kontrolündeki bir objeyi listBox2 ye sürükeyip bırakarak listBox2 içine aktarılmasını sağlayacağız. Yani hikaye bazında anlatmamız gerekirse “Tüm Programcılar”ı listBox1 de görüntüleyip “C# Kullananlar” ı listBox2′ye sürükleyerek ayrıştıracağız.

ilk olarak listBox1 deki bir Item’ı seçmek için listBox1 in MouseDown özelliğinden faydalanacağız.
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
Point snoktalar = new Point(e.X, e.Y);
int item_indis = listBox1.IndexFromPoint(snoktalar);
if (item_indis == -1)
{
MessageBox.Show("Boş bir alana tıkladınız. Boş alanda drag & drop gerçekleştiremezsiniz.");
return;
}
if (e.Button == MouseButtons.Left) {
listBox1.DoDragDrop(listBox1.Items[item_indis], DragDropEffects.All);
}
Şimdi bu kodlarımızı biraz açıklayalım… Öncelikle taşıma yönümüz listBox1 den listBox2′ ye doğru olduğu için. Taşınacak Objeye listBox1 içeriğinde tıklanacağından listBox1′imizin MouseDown eventine tıklama anında ne yapabileceğini belirtiyoruz.
İlk olarak Point sınıfından bir nesne türeterek listBox içinde tıkladığımız noktanın koordinat bilgilerini alıyoruz. Daha sonra listBox1 kontrolümüzün IndexFromPoint methodundan faydalanarak bu koordinatlarda hangi objenin varolduğunu indisine bakarak integer tipli item_indis değişkenimize aktarıyoruz.
Daha sonra kullanıcının listBox1 içerisinde Item içermeyen boş bir alana tıkladığını düşünerek kodlarımızın bu noktada hata vermemesini sağlamak için.
if (item_indis == -1)
{
MessageBox.Show("Boş bir alana tıkladınız. Boş alanda drag & drop gerçekleştiremezsiniz.");
return;
}
satırlarını ekliyoruz. Eğer kullanıcı listBox1 içerisinde Item içermeyen bir alana tıkladı ise Bu durumda IndexFromPoint methodu bize “-1″ değerini dönderecektir. Bizde böyle bir durum oluştuğunda kullanıcıya bilgi verip kodlarımızın o noktada durmasını sağlıyoruz.
Daha sonra kontrol üzerine mouse ile tıklamanın mouse’un hangi tuşu ile gerçekleştiğini inceliyor ve eğer sol tuş ile tıklanmış ise DoDragDrop methodu ile ilgili kontrolün ilgili Item’nin taşıma işlemine başlamasını sağlıyoruz. DragDropEffects parametresine verdiğimiz All değeri ile de bu Item’in nasıl taşınabileceğini belirtiyoruz.
listBox1 ile işimiz bitti diyebiliriz. Objemizi seçtik ve taşımaya hazır konuma getirdik artık bu seçili objemizin listBox2 ye sürüklenip bırakılması ve bırakıldığı anda listBox2 içerisine aktarılmasını sağlayacağız. Bunun için listBox2 kontrolümüzün içerisine bir obje bırakılabilir olduğuna dair iznini vermemiz gerekir. Bu sebeple listBox2 nin AllowDrop özelliğini true yapıyoruz.

Artık objemizin listBox2 üzerinde sürüklenirkenki ve bırakıldığı andaki durumlarını ayarlamak kaldı.
Objemiz listBox2 nin üzerine geldiğinde yapılacak işlemleri belirlemek için listBox2′nin DragOver event’ini şu şekilde düzenliyoruz.
private void listBox2_DragOver(object sender, DragEventArgs e) {
if (e.KeyState == 1) {
e.Effect = DragDropEffects.All;
}
}
Buradaki DragEventArgs’dan türemiş e nesnemizin KeyState parametresi ile mouse ve klavyede o an hangi tuşa bastığımızı gözlemliyoruz. KeyState parametresi değer olarak
1 Mouse’un sol tuşuna basılıyor ise
2 Mouse’un sağ tuşuna basılıyor ise
5 Shift tuşuna basılıyor ise
9 Ctrl tuşuna basılıyor ise
gibi değerler alabileceği gibi kodumuzu
if ((e.KeyState & (8 + 32)) == (8 + 32))
{
e.Effect = DragDropEffects.All;
}
şeklindede yazabilir ve Ctrl + Alt tuşlarına basıldığında Drop işlemini gerçekleştirmesini sağlayabiliriz.
Burda sık kullandığımız bazı tuşların KeyState değerleride tablo halinde şu şekildedir.
8 Ctrl
32 ALT
4 Shift
(8+32) Ctrl + ALT
Son olarak Drop yani bırakılma durumunda programımızın nasıl davranacağını belirlemeye geldi. Drop olayı listBox2 nesnemizin üzerinde gerçekleşeceğinden listBox2 kontrolümüzün DragDrop event’ini şu şekilde düzenliyoruz.
private void listBox2_DragDrop(object sender, DragEventArgs e) {
listBox2.Items.Add(e.Data.GetData(DataFormats.Text));
listBox1.Items.Remove(e.Data.GetData(DataFormats.Text));
}
Burada’da gördüğünüz üzere Objemiz listBox2 üzerine sürüklenip bırakıldığı anda gerçekleşecek iki satır kodumuz var bunlardan birincisi
listBox2.Items.Add(e.Data.GetData(DataFormats.Text));
Drag durumundaki objemizi listBox2 içerisine eklemekte…
listBox1.Items.Remove(e.Data.GetData(DataFormats.Text));
Drop işlemi tamamlanıp Drag durumundaki objemizi listBox1 içerisinden kaldırıyoruz. Uygulamanızdaki kullanım alanına göre bu işlemi kullanmayabilirsiniz.
Uygulamamızın son görüntüsü

Buradaki kodlarımızın genel görünümümü kolaylık olsun diye ayrı yayınlayalım.
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
Point snoktalar = new Point(e.X, e.Y);
int item_indis = listBox1.IndexFromPoint(snoktalar);
if (item_indis == -1)
{
MessageBox.Show("Boş bir alana tıkladınız. Boş alanda drag & drop gerçekleştiremezsiniz.");
return;
}
if (e.Button == MouseButtons.Left) {
listBox1.DoDragDrop(listBox1.Items[item_indis], DragDropEffects.All);
}
}
private void listBox2_DragOver(object sender, DragEventArgs e) {
if (e.KeyState == 1) {
e.Effect = DragDropEffects.All;
}
}
private void listBox2_DragDrop(object sender, DragEventArgs e) {
listBox2.Items.Add(e.Data.GetData(DataFormats.Text));
listBox1.Items.Remove(e.Data.GetData(DataFormats.Text));
}
Evet basitçe C# ile Drag & Drop olayını bu şekilde gerçekleştirebiliriz. Giriş kısmında da belirttiğim gibi Drag & Drop olayının anlamlı olması açısından genel kullanımın DML işlemleri için geçerli olduğunu ve burda anlattıklarımın sadece Drag & Drop olayının anlaşılması için olduğunu unutmayın.
Yasin Sirkecili
yasin@csharpturk.net












fbsahin
Güzel Makale, Bilgiler için Teşekkürler…