Složená proměnná/objekt   otázka

VB.NET

Ve VB 2008 Express mám Checkboxy s parametrem name:

E#_Allow

kde # je číslo od 1 do 10 (je jich deset).

Potřeboval bych to projít cyklem, který vyhodnotí u každého z checkbobu, jestli je zaškrtnutý a podle toho se provede akce. Jenže nevím, jak vytvořit "složenou proměnnou", se kterou bych mohl pracovat. Hledal jsem sasi dvě hodiny na netu, ale nic jsem nenašel... Doufám že z kódu pochopíte, o co mi jde:

        For currnum As Integer = 1 To 10

            Dim obj As String = "E" & currnum & "_Allow" 'Tady jsem se marně pokoušel složit tu složenou proměnnou

            If CObj(obj).Checked = True Then 'A tady jsem se pokoušel to převést na objekt a použít v podmínce
                MsgBox(obj & " is checked!")
            End If

        Next

Program v kódu nehlásí chybu ale při zpracování už ano. Nevíte někdo, jak na to? Dalo by se to místo cyklu udělat i deseti podmínkami, ale to mi přijde příliš složité a nepraktické. Díky za odpověď.

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

Co byste řekl na CheckedListBox? To, co chcete by šlo samozřejmě udělat také, ale hlavně pro budoucí rozšiřitelnost aplikace by mohl být CheckedListBox vhodnější?

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

Ne, bohužel - tady tím checkboxem určuji, jestli chci použít nějakou skupinu dalších prvků, a listcheckbox bvby se moc nehodil. Každopádně díky za odpověď.m

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

V tom případě ano, už je mi to jasné. Tím pádem mi zbývá doporučit Vám řešení pana Michala Plška níže.

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

Nebylo by to šlo projít takto:

        For Each obj As Object In Pnl.Controls
            If TypeOf obj Is CheckBox Then
                Dim chb As CheckBox = DirectCast(obj, CheckBox)

                If chb.Checked Then
                    'něco
                    MessageBox.Show(chb.Name & " - checked")
                End If
            End If
        Next

nebo kontrolovaným checkboxům přiřadit něco do vlastnosti "Tag" (pokud jich tam máte víc), aby jste je poznal a projít je stejným způsobem.

        For Each obj As Object In Me.Controls
            If TypeOf obj Is CheckBox Then
                Dim chb As CheckBox = DirectCast(obj, CheckBox)

                If chb.Tag.ToString = "Identifikator" Then
                    If chb.Checked Then
                        'něco
                        MessageBox.Show(chb.Name & " - checked")
                    End If
                End If
            End If
        Next

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

Použil jsem první variantu, funguje, díky. Druhou jsme nezkoušel... Musím uznat, že takovéhle řešení by mě opravdu nenapadlo.

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

S vaší pomocí jsem se dostal dál, nicméně stojím před podobným problémem:

        For Each obj As Object In AllowPanel.Controls
            If TypeOf obj Is CheckBox Then
                Dim chb As CheckBox = DirectCast(obj, CheckBox)

                If chb.Checked Then
                    Dim row As String = chb.Text 'V chb.text mám uložené, kolikátý řádek ten checkbox je, jenže z toho bych zase potřeboval udělat složenou proměnnou, nebo to vyřešit jinak - ale jak, přes cyklus a elegantně?
                    For Each rowobj As Object In DirectCast(CObj(row), Panel).Controls 'A s tímhle jsem se marně pokoušel projít objekty na řádku (který je definován jako panel)
                        If TypeOf rowobj Is TextBox Then 'pokud je to textbox, chci mu oddělat readonly 
                            rowobj.readonly = False
                        ElseIf TypeOf rowobj Is Label Then 'Pokud label, chci červený text
                            rowobj.ForeColor = Color.DarkRed
                        End If
                    Next

                    IPCheck(En_IP) '

                Else '...v opačném případě chci udělat opak...

                    Dim row As String = chb.Text
                    For Each rowobj As Object In DirectCast(CObj(row), Panel).Controls
                        If TypeOf rowobj Is TextBox Then
                            rowobj.readonly = True
                        ElseIf TypeOf rowobj Is Label Then
                            rowobj.ForeColor = Color.Black
                        End If
                    Next

                End If

            End If
        Next


    End Sub

Kód a komentáře v něm doufám mluví za vše. Díky za odpověď.

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

Procházíte pokud to chápu kolekci nějakého jiného panelu, jehož název máte uložen ve vlastnosti text checkboxu.

        For Each rowobj As Object In DirectCast(CObj(row), Panel).Controls 

zkuste si přímo konkrétní objekt panel náležící k checkboxu uložit ne do vlastnosti chb.text, ale do chb.tag do té jde ukládat přímo objekt (asi ne v designeru, ale v kodu vpohodě)

př.: me.checkbox1.tag = me.panel1

pak by cyklus

For each rowobj as object in directcast(me.chb.tag,panel).control
Next

měl fungovat

Všechny přetypovávací funkce používají Object na něco, vy přetypujete (Dim row As String = chb.Text) string na Object CObj(row), ale to není objekt panelu, ale toho stringu.

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

Funguje, díky.

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

K vašemu řešení bych měl jednu výhradu. V cyklu máte DirectCast(Me.chb.Tag, Panel).Controls což je přetypování, ale zřejmě si neuvědomujete, že takto zapsáno se to přetypování bude provádět při každém průchodu, což je zbytečně náročné. Řešení by bylo:

Dim myControls = DirectCast(Me.chb.Tag, Panel).Controls
For Each rowobj As Object In myControls
Next

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

Já bych to uděl takzvaně " Hezky česky po anglicky ":

        Public Class Form1
    Dim a As New CheckBox()

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        For currnum As Integer = 1 To 2
            a = CObj(Me.Controls("CheckBox" & currnum.ToString()))
            If a.Checked = True Then
                MsgBox("ChecBox " & currnum.ToString() & " je zaškrtnut!")
            End If

        Next

    End Sub
End Class

Je to docel jednoduché, vytvoříte si v paměti jeden checkbox do kterého v cyklu "přiřazujete" to co máte na formu. A vlastnosti toho "áčka" můžete používat.

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

Tak zrovna v tomhle případě je to naprosto zbytečné, protože se používá pouze jedna vlastnost a to přetypování je nutné provádět vždy. Rovněž cyklus od 1 do 2 a vyhledávání prvků v kolekci skládáním názvů je naprosto nevhodné a neefektivní, sem se právě hodí cyklus For Each Control a kontrola typu prvku.

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