TextBoxy v cyklu   zodpovězená otázka

VB.NET, WinForms

Zdravím, potřeboval bych rozchodit, aby se mi po vybrání patřičné hodnoty (číslo 2-9) z ComboBoxu vypsalo po sebe tolik TextBoxů. Zkoušel jsem to pomocí

Me.Controls.Add(new_textbox)

ale vytvořilo se jednom jedno.

Takto to mám v cyklu:

Dim new_textbox As New TextBox
            new_textbox.Name = "TextBox_" & i + 2
            new_textbox.Width = Me.TextBox_2.Width
            new_textbox.Height = Me.TextBox_2.Height
            new_textbox.Location = New Point(Me.TextBox_2.Location.X, i * (Me.TextBox_2.Location.Y + distance))

Prosím o radu, díky ;)

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

Zkuste poslat celý kód včetně cyklu. Je důležité kde je umístěn řádek:

Me.Controls.Add(new_textbox)
nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Samozřejmě se nejedná o finální verzi, jen zkouším funkčnost :)

Private Sub New_Test_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim distance As Integer = 32
        Dim i As Integer = 1

        While (i <= 5)
            Dim new_label As New Label
            new_label.Name = "Label_" & i + 2
            new_label.Text = i + 2
            new_label.Width = Label_2.Width
            new_label.Height = Label_2.Height
            new_label.Location = New Point(Me.Label_2.Location.X, i * (Me.Label_2.Location.Y + distance))
            Me.Controls.Add(new_label)

            Dim new_textbox As New TextBox
            new_textbox.Name = "TextBox_" & i + 2
            new_textbox.Width = Me.TextBox_2.Width
            new_textbox.Height = Me.TextBox_2.Height
            new_textbox.Location = New Point(Me.TextBox_2.Location.X, i * (Me.TextBox_2.Location.Y + distance))
            Me.Controls.Add(new_textbox)

            Dim new_checkbox As New CheckBox
            new_checkbox.Name = "CheckBox_" & i + 2
            new_checkbox.Text = "Správně?"
            new_checkbox.Width = CheckBox_2.Width
            new_checkbox.Height = CheckBox_2.Height
            new_checkbox.Location = New Point(Me.CheckBox_2.Location.X, i * (Me.CheckBox_2.Location.Y + distance))
            Me.Controls.Add(new_checkbox)

            i += 1
        End While
    End Sub
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Do nového prázdného Formu1 nakopírovat:

Imports System.Windows.Forms
Public Class Form1
    Dim cb As ComboBox
    Const dist As Integer = 4
    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()
        cb = New ComboBox
        With cb
            .Top = dist
            .Left = dist
        End With
        Me.Controls.Add(cb)
        AddHandler cb.SelectedIndexChanged, New EventHandler(AddressOf ComboBox_SelectedIndexChanged)
        For i As Integer = 2 To 9
            cb.Items.Add(i.ToString)
        Next
    End Sub

    Private Sub ComboBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim c As Integer = CType(DirectCast(sender, ComboBox).Text, Integer)
        For i As Integer = 1 To c
            Dim tb As TextBox = New TextBox
            With tb
                .Name = "TextBox_" & i
                .Top = (i - 1) * .Height + i * dist
                .Left = cb.Right + dist
                .Text = .Name
            End With
            Me.Controls.Add(tb)
        Next
        cb.Enabled = False
    End Sub
End Class

Jen pokus... Mnoho zdaru!

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

Děkuji za reakci, nechal jsem se inspirovat a zapracoval to do svého.. samozřejmě Váš kód funguje, ale nechápu, proč nefunguje můj :'(

Imports System.Windows.Forms

Public Class New_Test
    Const distance As Integer = 32
    Const nbr_rows As Integer = 5
    Const max_limit As Integer = 20

    Private Sub New_Test_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For i As Integer = 2 To max_limit
            ComboBox_Pocet_Odpovedi.Items.Add(i)
        Next
    End Sub

    Private Sub ComboBox_Pocet_Odpovedi_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox_Pocet_Odpovedi.SelectedIndexChanged
        For i As Integer = 1 To CType(ComboBox_Pocet_Odpovedi.SelectedItem.ToString, Integer) - 2
            Dim tb As TextBox = New TextBox
            With tb
                .Name = "TextBox_" & i + 2
                .Top = i * (Me.TextBox_2.Location.Y + distance)
                .Left = Me.TextBox_2.Location.X
                .Text = .Name & i + 2
            End With
            Me.Controls.Add(tb)
        Next
    End Sub
End Class

Já totiž COmboBox mám napevno umístěný ve formuláři, ale předpokládám, že by to tak mělo být jednodušší :)

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

Zkoušel jsem i úpravy, ale totožný kód zkrátka nefunguje. Nevíte, v čem je problém?

Public Class New_Test
    Dim ComboBox_PocetOdpovedi As ComboBox                  'Instance ComboBoxu
    Dim xOfComboBox As Integer = 663                        'Pozice (x) ComboBoxu pro výběr počtu odpovědí.
    Dim yOfComboBox As Integer = 235                        'Pozice (y) ComboBoxu pro výběr počtu odpovědí.
    Dim maxComboAnswer As Integer = 9                       'Maximální počet odpovědí.
    Dim distanceOfAnswer As Integer = 32                    'Vzdálenost řádků odpovědí.

    Private Sub New_Test_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Přidá ComboBox pro výběr počtu odpovědí
        ComboBox_PocetOdpovedi = New ComboBox
        With ComboBox_PocetOdpovedi
            .Top = yOfComboBox
            .Left = xOfComboBox
            .Height = 13
            .Width = 117
        End With
        Me.Controls.Add(ComboBox_PocetOdpovedi)
        AddHandler ComboBox_PocetOdpovedi.SelectedIndexChanged, New EventHandler(AddressOf ComboBox_PocetOdpovedi_SelectedIndexChanged)
        For i As Integer = 3 To maxComboAnswer
            ComboBox_PocetOdpovedi.Items.Add(i.ToString)
        Next

    End Sub

    Private Sub ComboBox_PocetOdpovedi_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim lim As Integer = CType(DirectCast(sender, ComboBox).Text, Integer)
        For i As Integer = 1 To lim - 2
            Dim tb As TextBox = New TextBox
            With tb
                .Name = "TextBox_" & i + 2
                .Top = i * (Me.TextBox_2.Location.Y + distanceOfAnswer)
                .Left = Me.TextBox_2.Location.X
                .Width = Me.TextBox_2.Width
            End With
            Me.Controls.Add(tb)
        Next
        ComboBox_PocetOdpovedi.Visible = False
        Label5.Visible = False
        Label6.Visible = False
    End Sub

End Class

Vypíše to jenom jedno textové pole (na správnou pozici), ale jenom jedno, ikdyž vyberu v ComboBoxu více.. :(

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

ked som

For i As Integer = 1 To lim - 2

zmenil na

For i As Integer = 1 To lim - 1

tak mi to zrazu islo :)

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

To převádění stringu na Integer přes CType, to je šílené, nepoužívejte to. Buď použijte CInt, nebo Convert.ToInt32 (dělají víceméně to samé), případně Integer.TryParse, pokud nechcete, aby při špatném vstupu nastala výjimka.

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

Díky, do příště se polepším :) Chybu jsem obejvil, zjistil jsem, že jsem absolutní poleno, jelikož jsem v cyklu násobil cca. hodnotu 300 x i, kde i = 1, 2, 3,.. pro pozici od vrhu w. formu :)

jinak všem díky za příspěvky..

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

Omluva, že jste slíznul to mé šílené CType.

...

Zdá se, že jde o formulář pro nějaké testy...

Jen nápad, zda nepoužít místo textboxů třeba

datagridview a netřeba prvky rovnat...

Textový sloupec pro otázky, hned vedle sloupec

pro odpovědi a třetí skrytý pro vyhodnocení.

Nebo otázka a varianty (a,b,c), vedle sloupec

s checkboxy pro zatrhávání správných odpovědí

a sloupec s bodovým ohodnocením.

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

No toto mi zatím stačí, pokud to rozchodím, budu spokojen :))

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

Ještě jsem narazil na další malý problém. Za běhu programu se mi generují v cyklu checkboxy:

Dim chb As New CheckBox
            With chb
                .Name = "O_chb_" & i
                .Top = StartPosY + (VzdalenostRadku * i) - 2
                .Left = tb.Right + 20
                .Text = "Správně?"
            End With
Me.Controls.Add(chb)

To funguje už bez problémů. Nyní ale potřebuju zjistit (zřejmě přes Handler), který CheckBox je zaškrtnutý. Zkoušel jsem všechny možné události přes handlery, ale nedaří se mi to rozhodit.. potřeboval bych ta výsledná data uložit zřejmě do kolekce, tedy něco jako:

cislo ot. (key) zaskrnute? (value)

1 0

2 1

3 1

4 0

Díky za nápady ;)

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

Otázky a odpovědi, pro potřebu nějakého testu, kvízu apod.

Zajímavé natolik, že se pokouším záměr rozvinout a přispět

vlastním nápadem.

Zohledněna možnost vybrat jen jednu správnou odpověď

pro danou otázku nebo více správných odpovědí a místo

počtu správných otázek sčítat body za otázku a nakonec

provést vyhodnocení. Nutno ještě nápad rozvinout...

Součet vypočítaného sloupce datatable pomocí Compute.

Do kódu form1 vložit:

Public Class Form1
    Dim dt1 As DataTable
    Dim dt2 As DataTable
    Dim WithEvents dgv1 As DataGridView
    Dim WithEvents dgv2 As DataGridView
    Dim bs As BindingSource
    Dim ss As StatusBar
    Dim b1 As Boolean

    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        Me.Text = "QuestionsAndAnswers"
        dt1 = New DataTable
        With dt1
            .Columns.Add("Číslo", Type.GetType("System.Int32"))
            .Columns.Add("Otázka", Type.GetType("System.String"))
            .Rows.Add(1, "Co je to ?")
            .Rows.Add(2, "Co je to ?")
            .Rows.Add(3, "Co je to ?")
        End With
        dt2 = New DataTable
        With dt2
            .Columns.Add("Číslo", Type.GetType("System.Int32"))
            .Columns.Add("Varianta", Type.GetType("System.String"))
            .Columns.Add("Odpověď", Type.GetType("System.String"))
            .Columns.Add("Vyber", Type.GetType("System.Boolean"))
            .Columns.Add("Body", Type.GetType("System.Int32"))
            .Columns.Add("Zisk", Type.GetType("System.Int32"), "IIf(Vyber,Body,0)")

            .Rows.Add(1, "a", "áčko", 0, 1)
            .Rows.Add(1, "b", "béčko", 0, 2)
            .Rows.Add(2, "a", "áčko", 0, 1)
            .Rows.Add(2, "b", "béčko", 0, 2)
            .Rows.Add(2, "c", "céčko", 0, 3)
            .Rows.Add(3, "a", "áčko", 0, 1)
            .Rows.Add(3, "b", "béčko", 0, 2)
            .Rows.Add(3, "c", "céčko", 0, 3)
            .Rows.Add(3, "d", "déčko", 0, 4)
        End With
        bs = New BindingSource
        bs.DataSource = dt2
        dgv1 = New DataGridView
        With dgv1
            .DataSource = dt1
            .Dock = DockStyle.Fill
            .SelectionMode = DataGridViewSelectionMode.FullRowSelect
            .MultiSelect = False
            .AllowUserToAddRows = False
            .ReadOnly = True
        End With
        dgv2 = New DataGridView
        With dgv2
            .Dock = DockStyle.Fill
            .MultiSelect = False
            .AllowUserToAddRows = False
            .DataSource = bs
            For i As Integer = 0 To .Columns.Count - 1
                If i <> 3 Then .Columns(i).ReadOnly = True
            Next
        End With
        Dim sc As SplitContainer = New SplitContainer
        With sc
            .Panel1.Controls.Add(dgv1)
            .Panel2.Controls.Add(dgv2)
            .Dock = DockStyle.Fill
        End With
        Me.Controls.Add(sc)
        ss = New StatusBar
        ss.Dock = DockStyle.Bottom
        Me.Controls.Add(ss)
        Dim ms As MenuStrip = New MenuStrip
        Dim tsmi As ToolStripMenuItem = New ToolStripMenuItem
        Dim tsmi1 As ToolStripMenuItem = New ToolStripMenuItem
        Dim tsmi2 As ToolStripMenuItem = New ToolStripMenuItem
        Dim tsmi3 As ToolStripMenuItem = New ToolStripMenuItem
        With tsmi
            .Text = "Menu"
            .DropDownItems.AddRange(New ToolStripMenuItem() {tsmi1, tsmi2, tsmi3})
        End With
        With tsmi1
            .Text = "One answer per question"
            .CheckOnClick = True
            .Tag = 1
            AddHandler .Click, New EventHandler(AddressOf tsmi_Click)
        End With
        With tsmi2
            .Text = "Total points"
            .Tag = 2
            AddHandler .Click, New EventHandler(AddressOf tsmi_Click)
        End With
        With tsmi3
            .Text = "User View"
            .CheckOnClick = True
            .Tag = 3
            AddHandler .Click, New EventHandler(AddressOf tsmi_Click)
        End With
        With ms
            .Dock = DockStyle.Top
            .Items.Add(tsmi)
        End With
        Me.Controls.Add(ms)
    End Sub

    Private Sub dgv1_SelectionChanged1(ByVal sender As Object, ByVal e As System.EventArgs) Handles dgv1.SelectionChanged
        Dim flt As String = "Číslo=" & dgv1.Rows(dgv1.CurrentRow.Index).Cells(0).Value.ToString
        If bs.Filter = flt Then Exit Sub
        bs.Filter = flt
        dgv1.AutoResizeColumns()
        dgv2.AutoResizeColumns()
    End Sub

    Private Sub dgv2_CurrentCellDirtyStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dgv2.CurrentCellDirtyStateChanged
        If dgv2.IsCurrentCellDirty And dgv2.CurrentCell.ColumnIndex = 3 Then
            If b1 Then
                For i As Integer = 0 To dgv2.Rows.Count - 1
                    If dgv2.Rows(i).Cells(3).Value = True And i <> dgv2.CurrentRow.Index Then
                        dgv2.Rows(i).Cells(3).Value = False
                    End If
                Next
            End If
            dgv2.CommitEdit(DataGridViewDataErrorContexts.Commit)
            dt2.AcceptChanges()
            ss.Text = IIf(b1, "Correct answers : ", "Total points : ") & dt2.Compute("Sum(Zisk)", "")
        End If
    End Sub

    Private Sub tsmi_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim tsmi As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)
        Select Case CInt(tsmi.Tag)
            Case 1
                Dim tsmi1 As ToolStripMenuItem = tsmi.OwnerItem
                b1 = tsmi.Checked
                tsmi1.DropDownItems(1).Text = IIf(b1, "Correct answers", "Total points")
                ss.Text = vbNullString
                For i As Integer = 0 To dt1.Rows.Count - 1
                    Dim b As Integer = 0
                    For j As Integer = 0 To dt2.Rows.Count - 1

                        If dt1.Rows(i).Item(0) = dt2.Rows(j).Item(0) Then
                            b = b + 1
                            dt2.Rows(j).Item(3) = False
                            If b1 Then
                                dt2.Rows(j).Item(4) = IIf(b = 1, 1, 0)
                            Else
                                dt2.Rows(j).Item(4) = b
                            End If
                        End If
                    Next
                Next
                dt2.AcceptChanges()
            Case 2
                Dim msg As String = tsmi.Text & " : " & dt2.Compute("Sum(Zisk)", "")
                If b1 Then
                    If dt1.Rows.Count = dt2.Compute("Sum(Body)", "") Then
                        msg = msg & vbCrLf & "Vše správně." & vbCrLf & "Congratulations!"
                    End If
                Else
                    If dt2.Compute("Sum(Zisk)", "") = dt2.Compute("Sum(Body)", "") Then
                        msg = msg & vbCrLf & "Plný počet bodů." & vbCrLf & "Congratulations!"
                    End If
                End If
                MsgBox(msg, MsgBoxStyle.Information, Me.Text)
            Case 3
                With dgv2
                    For k As Integer = 0 To .Columns.Count - 1
                        Select Case k
                            Case 0, 4, 5
                                .Columns(k).Visible = Not tsmi.Checked
                        End Select
                    Next
                End With
        End Select
    End Sub
End Class

Mnoho zdaru!

nahlásit spamnahlásit spam 1 / 1 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