Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB.NET: [VB.Net] Usercontrolin controllit

Sivun loppuun

novice [27.10.2010 10:07:19]

#

Moi!

Tein usercontrolin johon luodaan lennosta labeleita. Nyt haluaisin siihen myös VerticalScrollbarin, mutta sepä ei näy uc:ssa vasta kun lisään uc:iin jonkin toisen controllin joka ei näy uc:ssa vasta kun lisään uc:iin jonkin kolmannen controllin jne... Eli viimeksi lisätty controlli ei näy uc:ssa.

Mikähän tässä nyt mättää?

groovyb [27.10.2010 10:29:40]

#

pistäppä koodia

novice [27.10.2010 10:55:05]

#

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Uc_Listbox1.AddNewLabel()
    End Sub
End Class
Public Class uc_Listbox

    Private LBLs() As Label
    Public A As Long


    Public Sub New()
        InitializeComponent()
        CreateFirst_Lbl()
    End Sub

    Private Sub Format_lbl(ByRef Lbl As Label)
        With Lbl
            .AutoSize = False
            .Font = New Font("arial", 12)
            .Height = 20
            .Width = Me.Width - VSB.Width
            .BorderStyle = Windows.Forms.BorderStyle.None
            .Cursor = Cursors.Default
            .BackColor = Color.White
        End With

        AddHandler Lbl.Click, AddressOf Lbls_Click
    End Sub

    Private Sub CreateFirst_Lbl()
        Dim Lbl As Label = New Label
        Format_lbl(Lbl)
        Lbl.Location = New Point(0, 0)

        ReDim LBLs(0)
        LBLs(0) = Lbl

        DrawLabels()
    End Sub

    Public Sub AddNewLabel()
        Dim Lbl As Label = New Label
        Format_lbl(Lbl)
        Lbl.Location = New Point(0, LBLs.Length * (LBLs(0).Height))

        ReDim Preserve LBLs(LBLs.Length)
        LBLs(LBLs.Length - 1) = Lbl

        DrawLabels()

    End Sub

    Private Sub DrawLabels()
        For Each ctrl As Control In Me.Controls
            Me.Controls.Remove(ctrl)
        Next


        For i As Integer = 0 To LBLs.Length - 1
            If A = i Then
                LBLs(i).BorderStyle = Windows.Forms.BorderStyle.FixedSingle
            Else
                LBLs(i).BorderStyle = Windows.Forms.BorderStyle.None
            End If


            LBLs(i).Name = "lbl_" & i
            LBLs(i).Text = i
            Me.Controls.Add(LBLs(i))
        Next

        Me.Refresh()
    End Sub


    Private Sub Lbls_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim Lbl As Label = sender

        Dim temp() As String = Split(Lbl.Name, "_")
        A = temp(1)

        Form1.TextBox1.Text = A

        DrawLabels()
    End Sub

End Class

groovyb [27.10.2010 11:13:19]

#

Pistä breakpoint Drawlabels funktion me.refresh():iin, ja tarkista Me.Controls taulukko objekteista. jos viimeisin puuttuu, varmaan lähtisin ensin tarkastamaan menikö AddNewLabel funktion LBLs taulukon Redim oikein, ja jos meni, lähtisin tarkistamaan taulukon läpikäyntiä Drawlabels funktion for next loopista.

novice [27.10.2010 11:26:24]

#

Taisit nyt ymmärtää ongelman hieman väärin. Labelien piirto siis onnistuu ongelmitta, mutta Usercontroliin designer tilassa lisätty Scrollbar ei näy formilla ennen kuin Usercontroliin lisätään jokin controlli (esim toinen Scrollbar) joka taas ei näy formilla jne...

groovyb [27.10.2010 12:26:35]

#

voisi johtua siitä että tyhjennät kaikki kontrollit Drawlabelsissa ja lisäät ainoastaan Labeleita tyhjennystä seuraavassa for next loopissa.

kokeileppa tätä Drawlabels funktiossa tyhjennyksen suorittavan for each loopin sijaan:

Dim Deleteindex(Me.Controls.Count) As Integer
Dim index As Integer = 0
For Each ctrl As Control In Me.Controls
    Dim S() As String
    Dim Delimiter() As Char = ","
    S = ctrl.ToString().Split(Delimiter)
    If S(0) = "System.Windows.Forms.Label" Then
          Deleteindex(index) = 1
    End If
    index = index + 1
Next

For i As Integer = Deleteindex.Length - 1 To 0 Step -1
    If Deleteindex(i) = 1 Then
          Me.Controls.RemoveAt(i)
    End If
Next

Me.Refresh()

tällöin ainoastaan labelit poistuvat, ja lisäämäsi scrollbar tulisi jäädä.
taulukossa taaksepäin siksi, että kontrollien original indeksinumero muuttuu aina remove metodien jälkeen.

novice [27.10.2010 14:13:36]

#

Äh, no niinpä tietenkin!! olinpas minä typerä...kits groovyb!

homma hoituu yksinkertaisemmin myös tällä:

For Each ctrl As Control In Me.Controls
            If TypeOf ctrl Is Label Then
                Me.Controls.Remove(ctrl)
            End If
Next

EDIT: mutta miksi vain viimeksi uc:iin lisätty controlli poistuu em. loopissa?

groovyb [27.10.2010 14:56:00]

#

nyt en ymmärtänyt kysymystä ;)

lähinnä mitä looppia tarkoitat?

käytin kahta looppia sen vuoksi, että kontrollit käydään viimeisestä poistettavasta alkaen läpi. koska kun me.controls[0] poistetaan, vanhasta controls[1]:stä tulee controls[0]. jos se nyt selventää yhtään ;)

novice [27.10.2010 17:14:32]

#

Juu, ymmärsin lähettämäsi koodin täysin, ja ongelmani on jo ratkennut.

Jäin kuitenkin miettimään tätä..

novice kirjoitti:

... mutta sepä ei näy uc:ssa vasta kun lisään uc:iin jonkin toisen controllin joka ei näy uc:ssa vasta kun lisään uc:iin jonkin kolmannen controllin jne... Eli viimeksi lisätty controlli ei näy uc:ssa.

For Each ctrl As Control In Me.Controls
            Me.Controls.Remove(ctrl)
Next

Miksi tuo koodi poistaa vain viimeksi lisätyn kontrollin?

groovyb [27.10.2010 18:33:29]

#

tee tuo koodinpätkäsi uudestaan,pistää breakpointilla eteenpäin, ja katso mitä tapahtuu.

for each looppi ei toimi niinkuin pitää, vaan poistaa joka toisen kontrollin.

tämä siksi että tosiaan remove metodit sotkee indeksinumerot Me.controls taulukosta.

oletetaan että löytyy 6 Labelia taulukosta, jotka poistetaan kyseisellä for each loopilla

(0)label (teksti: 0)
(1)label (teksti: 1)
(2)label (teksti: 2)
(3)label (teksti: 3)
(4)label (teksti: 4)
(5)label (teksti: 5)

okei, ensin poistuu numero (0)label, jonka jälkeen taulukko on seuraava:

(0)label (teksti: 1)
(1)label (teksti: 2)
(2)label (teksti: 3)
(3)label (teksti: 4)
(4)label (teksti: 5)

nyt ollaan indeksinumerossa 1 loopissa, jolloin poistuu (1)label, ja jäljelle jää:

(0)label (teksti: 1)

(2)label (teksti: 3)
(3)label (teksti: 4)
(4)label (teksti: 5)

jotka taas indeksoituvat automaattisesti:

(0)label (teksti: 1)
(1)label (teksti: 3)
(2)label (teksti: 4)
(3)label (teksti: 5)

formilla olisi loopin lopussa jäljellä alkuperäiset labelit nro: 1, 3 ja 5

tee vaikka uusi projekti ja kokeile tätä seuraavaa koodia, ja katso mitä jää jäljelle:

Dim y As Integer = 40
For i As Integer = 0 To 5
    Dim _L As New Label
    _L.Text = i.ToString()
    _L.Location = New Point(10, Y)
    _L.Size = New Size(100, 40)
    Me.Controls.Add(_L)
    y = y + 40
Next

For Each ctrl As Control In Me.Controls
    Me.Controls.Remove(ctrl)
Next

Me.Controls.Clear() poistaisi kaikki kontrollit suoraan,siihen ei looppeja tarvita.

novice [27.10.2010 20:42:10]

#

Hienoa, tuohan selvitti tämän hetkisenkin ongelman!


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta