C#’ta ListBox ve CheckedListBox

Windows Formlarıyla çalışırken listbox(bundan sonra lb olarak anılacak) ve checkedlistbox’ları(bundan sonra chlb olarak anılacak) çok kullanıyorsanız bunlardaki eleman ekleme, çıkarma, seçme v.s gibi işlemleri ilk başlarda çok karışık bulabilirsiniz. Umarım bu gönderim bu konuya yeni girenler için faydalı olur.

Not:Aşağıda hem chlb hem lb’den herhangi birini kastetmek için Control ifadesini kullandım.

Edit:Kodlardaki kucuk buyuk isaretleri ve turnak isareti defalarca duzeltmeme ragmen garip cikiyor. Free uyelik oldugu icin bunlarin duzelmesini saglayan kodu da ekleyemiyorum malesef. Copy paste yaptiktan sonra kendiniz de replace edebilirsiniz.

İyi kodlamalar

A)Giriş

Aşağıdaki gibi bir form tasarlıycaz, en alttaki linkte kaynak solution dosyasına ait link bulunmaktadır. Soldaki gibi bir chlb’mız olacak  ve buna rastgele sayılar ekleyip çıkaracağız, sağda ise bir lb olacak, buna da çeşitli harfleri ekleyip çıkarıcağız, ayrıca soldaki kutudan buna transfer yapacağız.

chlb-ve-lb

B)Nedir, nasıl yapılır?

1.Kritik üyeler

1.1.Her iki Control için de ortak üyeler

Item: Control içindeki elemanın kendisidir. Dönüş değeri objedir, çünkü liste içindeki elemanlar belirli bi veri tipinden olmak zorunda değil; bi eleman integer iken bir diğeri string olabilir. Item, bir obje olduğu için bununla ilgili stringsel bir işlem yapılmadan önce ToString ile string değeri elde edilmelidir. Keza eğer hepsi numerikse ve matematiksel işlem yapılacaksa da Convert sınıfı ile uygun sayı tipine dönüştürülmelidir.

Items: Tüm elemanların koleksiyonudur. Genelde eleman ekleme, çıkarma ve sayma için kullanılır.

Index: Elemanların liste içindeki sırasıdır, tek başına bir kullanımı yok hatta böyle bir member bile yok, ancak SelectedIndices gibi bazı propertyler içine parametre olarak gider.

SelectedItem: Seçili elemanın kendisidir.

SelectedItems: Seçili elemanların koleksiyonudur.

SelectedIndex: Seçili olan(işaretli değil) kaydın indexini verir, integer döndürür. Genelde checkedListBox1.Items.RemoveaAt(…) içinde veya bir seçim yapılmış mı diye kontrol etmek için veya herhangi bir seçim varsa seçimi sıfırlamak için  (chlb.selectedindex = -1) kullanılır.

SelectedIndices: Seçili elemanların indexlerinin toplam grubunu verir, genelde kullanım şekli bu koleksiyonun dizi numarasını vererek bunu lb’tan çıkarma veya for/while/until/if ile bunun belli bir değerde olup olmadığını kontrol etme şeklindedir.

listbox1.Items.RemoveAt(listbox1.SelectedIndices[0])  veya

for (int i = listBox1.SelectedIndices.Count – 1; i >= 0; i–) gibi

ClearSelected:Tüm seçimleri kaldırır.

GetSelected(index): Verilen indexteki elemanın seçili olup olmadığını verir.

SetSelected(index,boolvalue): Verilen indexteki elemanı seçer(true ise), veya seçimi kaldırır(false ise)

1.2.Sadece cheklistbox için geçerli olan üyeler

CheckedItems: İşaretli elemanların bir koleksiyonunu verir.

ChekecedIndices: İşaretli elemanların indexlerinin bir koleskiyionunu verir

GetItemChecked(index): Verilen indexli elemanını işaretli olup olmadığını döndürür.

GetItemCheckState(index): Verilen indexli elemanını işaret durumunu gösterir (3 durumdan 1’i, seçili, seçil değil, gri seçili(yarı seçili yarı seçimsiz))

SetItemChecked(index,boolvalue): Verilen indexli elemanın işaretler veya işaretsiz bırakır

SetItemCheckState(index, checkstate): Verilen indexli elemana verilen işaret durumunu atar(3 durumdan 1’i)

1.3.Sadece listbox için geçerli olan üyeler

SelectionMode: Bir seferde tek eleman mı yoksa çoklu eleman mı seçileceğini belirtir. Çoklu seçimde kendi içinde ikiye ayrılır: Shift tuşuyla peşpeşe seçim yapılabilecekse MultiExtended, tek tek çoklu seçim yapılacaksa MultiSingle seçilir.

2.Çeşitli İşlemler

İşlemleri aşağıdaki gibi 3 gruba ayırabiliriz

  • Eleman ekleme-çıkarma(Tekli,çoklu,tüm)
  • Eleman seçme-seçimi kaldırma(Tekli,çoklu,tüm)
  • Bilgi edinme(Seçim durumu, işaret durumu, belirli bir eleman listede mi?)

2.1.Eleman ekleme

Her iki kontrol için de yöntem basit ve aynıdır:

Control.Items.Add(eleman)

veya bir List öğesi içindeki tüm elemanlar da her iki Controle eklenebilir.

var listem=new List<String>();
listem.Add("elma");
listem.Add("armut");
listem.Add("karpuz");
listBox1.SourceControl=listem

2.2.Eleman çıkarma

Remove: Parametre olarak elemanın kendisini alır

RemoveAt: Parametre olarak elemanın index numarasını alır. (index numarası genelde direkt bir numara değil de bun numarayı veren dolaylı bir ifade olur)

2.2.1.Tekil eleman çıkarma

Chlb’de işaretli elemanın listeden çıkarılması sözkonusyken, Selectedindexin benzeri bir Checkedindex özelliği olmadığı için RemoveAt yerine Remove kullanırız. Keza yine SelectedItem’a benzer bir CheckedItem olmadığı için chlb’da işaretli elamanı silmenin en basit yolu, onu işaret index nosu ile yakalayıp silmektir, yani ilk index no olan 0 ile.

checkedListBox1.Items.Remove(checkedListBox1.CheckedItems[0]);

lb’ta ise seçili elemanı çıkarma konusunda birden çok yöntem karşımıza çıkar. chlb için de seçili elemanın çıkarılma yöntemleri aynıdır, ama chlb’ta seçili elemandan ziyade daha çok işaretli elemanla ilgili işlemler yapılmaktadır.


//1.yöntem:seçilenin indexine göre
listBox1.Items.RemoveAt(listBox1.SelectedIndex);

//2.yöntem:zorlama bir yöntem ama teorik olarak olur. chlb'ta checkliler için de aynı mantıkla yapıyoruz
listBox1.Items.RemoveAt(listBox1.SelectedIndices[0]);

//3.yöntem:selecteditem
listBox1.Items.Remove(listBox1.SelectedItem);

//4.yöntem:yine zorlama bi yol, selecteditems ile
listBox1.Items.Remove(listBox1.SelectedItems[0]);

2.2.2.Çoklu eleman çıkarma

Eleman çıkarma konusunda MSDN bizi foreach döngüsü kullanmamamız gerektiği konusunda uyarıyor, foreach sadece elemanların üzerinden tek tek geçmek için kullanılmalı diyor. Çünkü foreach’te arkaplandaki collectionun içeriğini her defasında değiştirmiş ve enumaratorü bozmuş oluyoruz.

Normal for döngüsünde ise elemanların kendisi üzerinde değil indeksleri üzerinde hareket ettiğimiz için böyle bir sorunumuz olmuyor, bu yüzden normal for döngüsü veya aşağıda göreceğimiz diğer yöntemler kullanılabilir.

chlb için


for (int s = 0; s < checkedListBox1.CheckedItems.Count; s++)
{
checkedListBox1.Items.Remove(checkedListBox1.CheckedItems[s]);
s--;
}

lb için


//1.yöntem:for dögüsü. liste içeriğini değiştirme işlemleri for eachle olmuyor, foreach buna uygun değil, o yüzden normal for döngüsü yapıyoruz

for (int i = listBox1.SelectedItems.Count - 1; i <= 0; i--)
{
listBox1.Items.RemoveAt(listBox1.SelectedIndices[i]);
}

//2.yöntem while ile
while (listBox1.SelectedItems.Count < 0)
{
listBox1.Items.Remove(listBox1.SelectedItems[0]);//çoklu seçimlerde ilk seçili olan 0 indekslidir, biz de her defasında bu ilk seçili olanı siliyoruz, ta ki seçili kalmayana kadar
}

//3.yöntem yine while ile ama farklı türlü
while (listBox1.SelectedIndex != -1) //seçili kayıt olmayadığ sürece demek
{
listBox1.Items.RemoveAt(listBox1.SelectedIndex);
}

//4.yöntem
ListBox.SelectedObjectCollection secililer = new ListBox.SelectedObjectCollection(listBox1);
secililer = listBox1.SelectedItems;

for (int i = secililer.Count - 1; i <= 0; i--)
{
listBox1.Items.Remove(secililer[i]);
}

//5.yöntem:geçici olarak bi listte toplamak

ArrayList gecicidizi = new ArrayList();
foreach (object obj in listBox1.SelectedItems)
{
listBox2.Items.Add(obj);
gecicidizi.Add(obj);
}
foreach (object obj in gecicidizi.ToArray())
{
listBox1.Items.Remove(obj);
}

//6.yöntem:5.yönteme benzer şekilde geçici bir dizide toplamak
object[] silinecekler = new object[listBox1.SelectedItems.Count];
listBox1.SelectedItems.CopyTo(silinecekler, 0);

foreach (object item in silinecekler)
{
listBox1.Items.Remove(item);
}

2.2.3.Tüm elemanları çıkarma(Listeyi boşaltma)

//iki kontrol için de aynıdır
Control.Items.Clear();

2.3.Eleman seçme/işaretleme

2.3.1.Tek elemanı işaretleme ve seçme

İşaretleme:checkedListBox1.SetItemChecked(index, boolvalue): Sadece chlb’de geçerli. İlgili elemanı belirtilen check durumuna getirir, yani işaretli veya işaretsiz. Seçim için boolvalue olarak true demeliyiz. Buna benzer bir de SetItemCheckState(index, chekstate) var, bunun ikinci parametresi ise 3’lü enum değerleridir:seçili, seçimsiz, undetermined(gri seçimli)

Seçme: Her iki kontrolde de SetSelected(index,boolvalue) şeklinde kullanılır. boolvalue true olursa seçer, false olursa seçimi kaldırır

2.3.2.Çoklu Seçme/işaretleme

chlb’larda selectionmode özelliği multi yapılamıyor, o yüzden çoklu seçim yapamıyoruz, sadece işaretlemenin multisini yapacağız.

chlb’ın multi işaretlemesi şöyle(3-9 arası indexli elemanlar işaretlenecek)

for (int i = 3; i < 10; i++)
{
checkedListBox1.SetItemChecked(i, true);
}

lb’ın multi seçimi ise şöyle(chlb için de aynıdır)

for (int i = 3; i < 10; i++)
{
listBox1.SetSelected(i, b);
}

2.3.3.Tüm elemanları seçme/işaretleme

Bunun için özel bir metod yok, çoklu yöntemi kullanılır.

for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
checkedListBox1.SetItemChecked(i, true);
}

2.4.Seçim/İşaret Kaldırma

2.4.1.Tek elemandaki seçimini/işaretlemeyi kaldırma

Her iki kontrolde de seçme/işaretleme sırasında true atadığımız parametreyi false atarız.

2.4.2.toplu seçim/işaret kladıma

2.4.2.1.lb’den toplu seçim kaldırma(chlb için de aynsı geçerli)

Seçili olanların seçimin iptal etmekle tüm kayıtları seçimsiz hale getirmek teorikte aynı şeydir, o yüzden tüm kayıtları seçimsiz hale getiren pratik kodlardan herhangi birini(aşağıdaki yöntemlerden ilk 2si) uygulayabiliriz, ancak seçimi kaldırırken başka işlemler de yapılacaksa döngü kullanmak gerekir.

//1.yöntem:inbulit metod ile
listBox1.ClearSelected();

//2.yöntem, olmayan kaydın seçimi
listBox1.SelectedIndex = -1;

//Bununla beraber seçimi kaldırırken aynı anda başka bir işlem de yapmak için for döngüsü kullanılabilir. Bu arada birçok yerde for döngüsünü listedeki tüm kayıtlar için yapıldığna dair örnek kodlar veriliyor, habluki doğrusu sadece seçili kayıtlar üzerinden gitmektir. küçük listelerde bu sorun teşkil etmez ama büyük bir liste varsa o zaman performans sorunu olabilir.
//3.yöntem:for döngüsü
for (int i = 0; i < listBox1.SelectedItems.Count; i++)
{
listBox1.SetSelected(listBox1.SelectedIndices[i], false);
i--;//i'nin hiç artmamasını sağlıyorum, böylece her iterasyonda hep 0. indexteki eleman üerinde işlem yapmış oluyorum
//burada diğer işlemler yapılabilir.
}
//4.yöntem:hep 0 indexli kaydın işaretini kaldırmanın bir yolu da while döngüsüdür
while (listBox1.SelectedItems.Count < 0)
listBox1.SetSelected(listBox1.SelectedIndices[0], false);
2.4.2.2.chlb için toplu İşareti kaldırma

chlb sözkonusu olduğunuda seçimleri kaldırırken kullandığımız ClearSelected gibi ClearChecked diye bir metod yok, ayrıca  -1’li indexi işaretlemek diye de bir seçenek yok, ama başka çözümler var tabiki, hemen aşağıda.

//1.çözüm:tüm kayıtların üzeirnden geçerek hepsindeki işareti kaldırmakak:dezanvantajı şu:yüzlerde kayıt varsa ve sen sadece seili olan 2-3 kayıttakini kaldımrak isityorsan boşuna tüm kayıltaır dolaşmış olursun, ama tabi yine de hepsi 1-2 sn'de seçilir
for (int i = 0; i < checkedListBox1.Items.Count ; i++)
{
checkedListBox1.SetItemChecked(i, false);
}
//2.çözüm:yinei for döngüsü ama bu sefer sadece seçil kayıtlar üzerinden geçmek
for (int i = 0; i < checkedListBox1.CheckedItems.Count; i++)
{
checkedListBox1.SetItemChecked(checkedListBox1.CheckedIndices[i], false);
i--;//i'nin hiç artmamasını sağlıyorum, böylece her iterasyonda hep 0. indexteki eleman üerinde işlem yapmış oluyorum
//burada diğer işlemler yapılabilir.
}

//3.yöntem:while döngüsü:hep işaretlilerden 0. indeksteki kaydın işaretini kadırıyoruz
while (checkedListBox1.CheckedIndices.Count < 0)
{
checkedListBox1.SetItemChecked(checkedListBox1.CheckedIndices[0], false);
}

 

C)Tüm Kod

Programın tamamına ait kodda başka bilgiler de var ancak nihai kod biraz uzun olduğu için buraya koymak yerine tüm solution dosyasını zipli olarak indirebileceğiniz bir link veriyorum, burdan indirebilirsiniz.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s