Makale Özeti

Bu yazımızda WPF Combobox kontrolünde çoklu seçim yapmamızı sağlayan örnek bir uygulama geliştireceğiz.

Makale

Geliştirdiğimiz uygulamalarda bazen varolan kontroller ihtiyacımızı karşılamaz. Bu durumda ya piyasadaki çeşitli .NET kontrollerini satın alabiliriz ya da kendimiz bu kontrolleri yazabiliriz. Ufak çaplı uygulamalarda bu kontrolleri almak pek de mümkün olmayabilir, yazmaksa zahmetli olabilir. Ama tam anlamıyla bir user kontrol olmasa bile işimizi görecek çapta bir kontrol hazırlamak WPF'le artık daha kolay.Bu fikirden yola çıkarak; combobox’ta birden fazla seçim yapmamızı sağlayan ufak bir uygulama yazdım.

Yapacağımız uygulamada amacımız AdventureWorks veritabanında bulunan alt kategorilerileri bir combobox’a doldurup daha sonra bu combobox’tan seçtiğimiz alt kategorilere ait ürünlerin sayılarını bir listbox’ta göstermek. Uygulamamıza veritabanına erişim için öncelikle Add->NewItem->Ado.Net Entity Data Model diyerek EDM’yi ekliyoruz.EDM’nin nasıl eklendiğini bilmeyenler için iTextSharp Kütüphanesi ile PDF Dosyasında Raporlar Oluşturmak bu makalenin başında anlatmıştım. Öncelikle Design kısmında Window’a combobox,button ve listbox nesnelerini ekliyoruz. Daha sonra kod kısmına geçip combobox’a dolduracağımız alt kategorileri getiren metodumuzu yazıp Constructor’da bu metodumuzu çağırıyoruz.

void Bind_cmbSubCat()

{

categories = de.ProductSubcategory.ToList();

cmbSubCat.ItemsSource = categories;

}

Buraya kadar iyi güzel ama metodu yazıp, ctor’da çağırmakla verimiz görüntüleniyor mu? Klasik Windows uygulaması olsaydı evet;ama WPF’te hayır. Peki bu gelen verileri görüntülemek için ne yapacağız? Bunun için tekrar xaml kısmına dönüyoruz. Combobox’ımızın ItemsSource property’sini (xml düşünürsek attribute) Binding olarak set ediyoruz.

Tabi bununla işimiz bitmiyor, şimdi combobox’ta verinin nasıl gösterileceğinin belirtmemiz gerek. Bunun için Combobox’ın DataTemplate elementini kullanıyoruz.

Yukarıda yazdığımız xaml’a bakacak olursak; combobox’ın DataTemplate elementi içerisinde bir checkbox kontrolünün bulunduğunu görüyoruz. Template oluşturma mantığını ASP.Net Repeater ve DataList kontrollerinden hatırlayacaksınız. Burada dikkat çekmek istediğim iki nokta var. Bunlardan biri Content, diğeri ise Tag attribute’larının içerikleri. WPF combobox kontrolünde klasik Windows Forms’daki Text property’sinin yerini Content attribute’u alıyor.(Aslında arka planda Content attribute’u bir property). Burada checkbox kontrolünün Content’inde veri kaynağımızdan gelen alt kategorilerin Name özelliğini göstereceğimizi belirtiyoruz. Tag attribute’unda ise o alt kategorinin Id değerini tutuyoruz. Bu değeri niye tuttuğumuzu birazdan görücez. Tekrar kod kısmına geçip bu seferde listbox kontrolünü doldurmak için gerekli olan metodumuzu yazıyoruz.

void Bind_lstCount()

{

var query = de.Product.Where(p => ids.Contains(p.ProductSubcategoryID.Value));

lstCount.ItemsSource = query.GroupBy(p => p.ProductSubcategoryID).Select(g =>

new

{

Id = g.Key,

Name = g.Select(p => p.ProductSubcategory.Name).FirstOrDefault(),

Count = g.Count()

});

}

Yukarıdaki metodu yazarken Linq To Entities’in verdiği iki ayrı hata ile karşılaştım. Biraz araştırma yapınca bu hataların sebebinin Linq To Entities’in bazı sorgulara destek vermeyişi olduğu yönünde sonuçlara ulaştım. Bu vesileyle de başka bir makale konusu çıkmış oldu karşıma :) Neyse biz konumuza dönelim. Yukarıdaki sorgularda önce ids adındaki listede bulunan alt kategorilere ait ürünleri alıyoruz, daha sonra bu ürünleri alt kategori id’lerine göre gruplayıp her bir alt kategorinin ürün sayısını alıyoruz ve bu sonucu listbox’ın ItemsSource’una bağlıyoruz. Şimdi de listbox kontrolünde verilerin nasıl gösterileceğini belirtelim. Yine burada Listbox kontrolünde de var olan DataTemplate elementini kullanıyoruz. Yukarıdakinden farklı olarak DataTemplate’in içine StackPanel atıyoruz. DataTemplate içerisinde birden fazla kontrol kullanacaksak bu kontrolleri içinde barındıracak (StackPanel,Grid) gibi kontroller kullanmak zorundayız. Kullanmadığımız durumda Desing zamanında The object 'DataTemplate' already has a child and cannot add 'TextBlock' şeklinde bir hata alıyoruz. StackPanel içerisine attığımız 1. Ve 3. TextBlock kontrollerinde veri kaynadığından gelen alt kategorinin Name özelliğini ve Count özelliğini göstereceğimizi belirtiyoruz.
 
Daha sonra combobox’ta seçme işlemini gerçekleştiriyoruz. Bunun için checkBox’ın Checked eventini kullanıyoruz.

private void CheckBox_Checked(object sender, RoutedEventArgs e)

{

CheckBox chk = (CheckBox)e.Source;

ids.Add((int)chk.Tag);

}

Yukarıda CheckBox’ın Tag elementinde alt kategori Id’sini tutmuştuk. Kendisi şimdi işimize yarayacak. Tag attribute object tipindendir ve belirli bir işlevi yoktur, buraya işinize yarayacak herhangi değeri atabilirsiniz. Hatta bir ürün nesnesi bile barındırabilirsiniz içinde. Burada Tag attribute’una bağladığımız Id değerini ids listesine ekliyoruz. Tabi bu arada seçmiş olduğunuz herhangi bir alt kategoriyi ids listesinden kaldırmak için de Unchecked eventini kullanıyoruz. Son olarak da button kontrolünün arasında listbox’ı dolduran Bind_lstCount() metodumuzu çağırıyoruz. Ve aşağıdaki gibi bir ekran görüntüsü elde ediyoruz.

Böylece bir makalemizin daha sonuna geldik. Bir sonraki makalede görüşmek dileğiyle hoşçakalın.