CheckedListBox   otázka

VB.NET

Ahoj, mám následující dotaz (VB.Net 2010). Potřebuji, aby se mi po zatržení CheckBoxu objevil v CheckedListBoxu určitý text a u něj zatržení. To mi funguje. Potřeboval bych však udělat, aby se mi při odstranění zatržení v CheckedListBoxu odstranilo i zatržení v CheckBoxu. Při vložení textové položky do CheckedBoxListu používám

Public Class Form1
    Dim položka As String
    Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
        If CheckBox1.CheckState = 1 Then
            položka = "lupenaté"
            CheckedListBox1.Items.Add(položka, True)
        End If

Položka se vloží a CheckBox u ní se zatrhne. Když pak odkliknu zatržení u položky v ChceckedListBoxu (musí se to provést tady), potřebuju, aby se mi zrušilo i zatržení příslušného CheckBoxu. Hledal jsem nějakou metodu, jak to provést, ale zatím jsem na nic nenarazil. Předem děkuju.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

CheckedListBox vyvolává událost ItemCheck, která je asi to, co hledáte. Pokud uživatel zaškrtne CheckBox v CheckedListBoxu, vyvolá se daná událost a jako argumenty události dostanete datový typ ItemCheckEventArgs, který obsahuje všechny důležité informace o položce, jako její index, starý a nový stav.

  Private Sub CheckedListBox1_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
    If CheckedListBox1.Items(e.Index) = "Položka" Then
      CheckBoxX.CheckState = e.NewValue
    End If
  End Sub

http://msdn.microsoft.com/en-us/library/... - ItemCheck na MSDN

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Ahoj, tohle bude asi ten správný způsob, ale neumím to rozchodit. Už si s tím hraju asi dvě hodiny a nefunguje to. Díval jsem se i na MSDN a přidal jsem si k tomu messageBox, který zobrazuje jednotlivé stavy události ItemCheck. Při odkliknutí políčka v CheckedListBoxu se však stav CheckBoxu nezmění. Výše uvedený příklad chápu jako: pokud se na položce "Položka" provede událost ItemCheck, změní se stav vlastnosti CheckBox1.CheckState na hodnotu e.NewValue. Co dělám špatně? Musím tu hodnotu ještě nějak přiřazovat?

Zkoušel jsem i následující variantu:

Private Sub CheckedListBox1_ItemCheck1(ByVal sender As Object, ByVal e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
        If (e.NewValue = CheckState.Unchecked) Then
            'If CheckedListBox1.Items(e.Index) = "položka" Then
            CheckBox1.CheckState = (e.NewValue)
        End If

Tady se to provede, ale program spadne a ohlásí chybu NullRefenceException Was Unhandled. Object reference not set to an instance of an object. Na to jsem krátký.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Udělal jsem ukázkový program. Z komentářů snad bude jasné, jak to funguje. Jsou tam nějaké chytáky, uvidíte sám. Nejsem si jistý, zda je to ideální řešení, ale funguje to. Heslo k RAR archivu je "vbnet".

http://mysharegadget.com/768369362

PS: Prosím, označujte vyřešená vlákna (Změna vlastnosti několika prvků najednou za běhu) jako zodpovězená - ať je na fóru pořádek :-). Děkuji.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Díky za poskytnutý příklad. Zatím se tomu snažím přijít na kloub (hlavně pochopit vlákna). Moc nechápu řádek

CheckBox1.Checked = položky.Except({položka}).Any(Function(p) CheckedListBox1.CheckedItems.Contains(p))

Nevím, jestli je nutná kontrola položek, k určitému CheckBoxu se vždycky vztahuje pouze jediná položka v CheckedListBoxu. Jeji odstranění by mělo být možné pouze odškrtnutím CheckBoxu, NE však v CheckBoxListu. Pokud se zruší zatržení u položky v CheckListBoxu, položka by měla zůstat (ale nezatržená) a mělo by se odstranit zatržení u příslušného CheckBoxu.

Možná bude lepší změnit koncepci chování prvků, kterou mám pro moji aplikaci vymyšlenou. Nechci blog zahlcovat popisem, jak by měl program fungovat a připadá mi, že už tak se tu moc roztahuju.

P.S. Jak označit vyřešené vlákno jako zodpovězené? Jenom v textu?

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Ta ukázka není vyloženě situace, kde by vlákna hrála nějakou roli, ale tím druhým vláknem jsem si pouze pomohl vyřešit ten konflikt přístupů, který nastal kvůli tomu, že události CheckBoxu a CheckedListBoxu byli tak úzce provázané. Vlákna jsou (zvenku) relativně jednoduchá a zajímavá, ale zatím pro Vás nejsou nutností, pokud uvážím, na jakém projektu pracujete.

Řádek, který jste označil, souvisí se scénářem, kdy je pod jedním CheckBoxem více položek v CheckedListBoxu. Vy jste tuto situaci vyloučil (ačkoliv pak mi uniká smysl použití CheckedListBoxu). Nicméně znamená následující (obecně):

Dim položky = New Integer() {1,2,3,4,5,6,7}
Dim položkySudé = položky.Except(new Integer() {1,3,5,7})
' položkySudé nyní obsahuje pole integerů s hodnotami 2,4,6

Except je extension metoda, která vrací všechno ze vstupní množiny, kromě množiny dané parametrem.Je definovaná pro rozhraní IEnumerable. IEnumerable je rozhraní, které se používá na všechny datové objekty, kterými lze iterovat. Cokoliv, u čeho můžete použít For Each (pole, List<T>, TreeNodeCollection etc.) implementuje rozhraní IEnumerable a tím pádem na to lze použít extension metoda Except.

Dim položky1 = New Integer() {1,2,3,4,5,6,7}
Dim položky2 = New Integer() {1,2,3}
Dim položky1podminka = položky1.Any(Function(p) p > 5) ' True
Dim položky2podminka = položky2.Any(Function(p) p > 5) ' False

Any je opět extension metoda. Je definovaná též pro IEnumerable (respektive IEnumerable<T> pro podporu generiky). Vrací vždy pravdivostní hodnotu, tedy True nebo False (Boolean) a vrací True, pokud alespoň jeden prvek vstupní množiny vyhoví podmínce. Podmínku jsem výše definoval lambda funkcí (Function(p) p > 5), ale může odkazovat i na existující funkci v kódu (jako parametr by se dosadilo AddressOf JménoFunkce).

Ještě malá poznámka ke generice. Jak vidíte, Except a Any budou fungovat na všem, co má enumerátor (tedy implementuje IEnumerable či Enumerable<T>. Jsou to totiž generické metody. Generické znamená, že mají typový parametr (T), stejně jako třeba seznam List(OF T) a když je potřeba, vytvoří se podle této šablony metoda (nebo třída) na míru danému typu. Napíšeme-li tedy v kódu něco jako Dim seznam = New List(Of String), při běhu programu se vytvoří nová třída, která nebude typu List(Of String), ale něco jako List`1blablabla, prostě unikátní identifikátor CLR. Tato třída stejně jako List(Of T) bude implementovat IEnumerable, takže se bude dát dosadit tam, kam List(Of String). Stejně tak generické funkce Except, Any (a všechny ostatní http://msdn.microsoft.com/en-us/library/... ) jsou definované jednou s daným typovým parametrem, ale budou fungovat pro jakýkoliv typ, který existuje v .NET frameworku, nebo pro Váš vlastní datový typ. Díky tomu můžeme použít Except a Any na pole integerů výše.

Zpět k vašemu problému - pokud tedy pro jeden CheckBox může být pouze jedna položka v CheckedListBoxu, nemá smysl CheckedListBox používat. Stejně tak, generování té položky by nemělo být při prvním zaškrtnutí CheckBoxu, ale například při načtení formuláře. Jestli Vám dobře rozumím, požadujete aby CheckBox měl závislý jiný CheckBox a:

1.) Zaškrtnu master = zaškrtnu slave

2.) Odškrtnu master = odškrtnu slave

3.) Zaškrtnu slave = nedělám nic pro master (?)

4.) Odškrtnu slave = odškrtnu master

Každopádně ať je to jak chce, toto je jednoduché pro prvky nakreslené v designeru. Předpokládám, že Vy prvky generujete dynamicky a proto jste sáhl po CheckedListBoxu, jelikož se do něj položky umisťují snadněji, než na formulář. Tomu rozumím, ale přesto si nemyslím, že je CheckedListBox ideální. Stejně tak můžete dynamicky vygenerovat CheckBox (slave) a provázat jeho události s master.

' Toto probíhá v Load formuláře
' Na formuláři už máme checkbox CheckBox1
Dim slaveCheckBoxForMaster1 = new CheckBox() With {.Text = "Lupenaté", Left = 12, Top = 24}
Controls.Add(slaveCheckBoxForMaster1)
AddHandler slaveCheckBoxForMaster1.CheckedChanged,
Sub(sender2 As Object, e2 As EventArgs)
  If Not DirectCast(sender2, CheckBox).Checked Then CheckBox1.Checked = False
End Sub
AddHandler CheckBox1.CheckedChanged,
Sub()
  slaveCheckBoxForMaster1.Checked = CheckBox1.Checked
End Sub

Píši to z hlavy, pravděpodobně tam budou nějaké nedostatky, ale myšlenka by měla být jasná. Máte hlavní CheckBox (CheckBox1), který si při design time přetáhnete na formulář. Máte vygenerovaný CheckBox (slaveCheckBoxForMaster1), který se při runtimu vytvoří v události Load formuláře a navěsíte jak jeho událost (na jejímž základě budete modifikovat hlavní CheckBox), tak navěsíte handler pro již existující hlavní CheckBox, aby ten mohl také ovlivňovat svůj podřízený CheckBoxu. Nejspíš bude třeba zavést příznak programováZměna podobně, jako jsem ho já uvedl ve své ukázce. Jde o to, že pokud CheckBox zaškrtnete, vyvolá se jeho událost a ta vyvolá zaškrtnutí podřízeného CheckBoxu, což vyvolá jeho událost a zaškrtne hlavní CheckBox, což vyvolá jeho událost a zaškrtne podřízený Checkbox, což... A tak dále. Pokud v programu budete zaškrtávat CheckBox, předtím dejte programováZměna = True a potom programováZměna = False, a do všech handlerů zaškrtnutí dejte jejich obsah do podmínky If Not programováZměna. Tím si zajistíte pouze reakci na akci uživatele, nikoliv programu.

U všech kromě prvního příspěvku ve vláknu by měl být odkaz "Označit jako odpověď" nebo podobný. U příspěvků, které na položený dotaz odpovídají tento odkaz následujte a tím by se mělo vlákno označit za vyřešené.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Děkuji za odpověď. Není to pro mě přesně ono, ale jsou to věci, které si odzkouším a nechám projít hlavou. Zkusím taky vymyslet nějaký jiný způsob, jak ten můj program koncipovat. Považujte to za ukončené a já dám chvíli pokoj. Díky. Honza.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback