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ää?
pistäppä koodia
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
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.
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...
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.
Ä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?
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 ;)
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?
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.
Hienoa, tuohan selvitti tämän hetkisenkin ongelman!
Aihe on jo aika vanha, joten et voi enää vastata siihen.