(solucionado) ¿clonar evento para varios elementos? ¿FOR?

Iniciado por Eleкtro, 18 Noviembre 2012, 12:39 PM

0 Miembros y 1 Visitante están viendo este tema.

Eleкtro

#20
Nada, gracias Hdm y Kubox, puse exactamente lo que me dijeron pero no me quiere funcionar esto:


Código (vbnet) [Seleccionar]
Public Class Form1
   Dim filesystem As Object, ThisDir As Object
   Dim mCheck(0) As CheckBox 'matriz que contendrá los "X" CheckBox
...



Código (vbnet) [Seleccionar]
   ' Form load
   Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
       foldertextbox.Text = My.Settings.folderpath
       updatecheckboxes()
   End Sub





1er intento:
El messagebox solo aparece 1 vez, y en el panel no aparece ningún checkbox.

Código (vbnet) [Seleccionar]
   ' update checkboxes
   Public Sub updatecheckboxes()
       Dim filesystem = CreateObject("Scripting.FileSystemObject")
       Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
       Dim i As Int32 = 0
       For Each folder In ThisDir.Subfolders
           i = i + 1
           Array.Resize(mCheck, i)
            mCheck(i - 1) = New CheckBox()
           MessageBox.Show("test")
           Me.Panel1.Controls.Add(mCheck(i))
           With mCheck(i)
               .Name = "Checkbox" & i
               .Text = folder.Name
               .Location = New Point(10, i * 20)
           End With
           AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox
       Next
       CargarPropiedad()
   End Sub





2ndo intento:

El msgbox aparece todas las veces,
se cargan todos los checkboxes,

Pero no puedo cerrar el form, y como he "omitido" el "Array.resize" y lo que me dijo el compañero Hdm pues no creo que el índice del "mcheck" funcione para cargar/guardar las settings

Además he vuelto a las mismas de antes declarando el mcheck con un valor alto (999), así que esto no creo que me sirva para nada, solo es un ejemplo.

Código (vbnet) [Seleccionar]
Public Class Form1
' el número aumentado a 999, sino no me funciona el segundo intento xD
   Dim mCheck(999) As CheckBox
...


Código (vbnet) [Seleccionar]
   ' update checkboxes
   Public Sub updatecheckboxes()
       Dim filesystem = CreateObject("Scripting.FileSystemObject")
       Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
       Dim i As Int32 = 0
       For Each folder In ThisDir.Subfolders
           i = i + 1
           mCheck(i) = New CheckBox()
           'Array.Resize(mCheck, i)
           MessageBox.Show("test")
           Me.Panel1.Controls.Add(mCheck(i))
           With mCheck(i)
               .Name = "Checkbox" & i
               .Text = folder.Name
               .Location = New Point(10, i * 20)
           End With
           AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox 'Asocio el evento CheckedChange del CheckBox actual a la función LlamadaCheckBox
       Next
       CargarPropiedad() 'Cargo las propiedades una vez dibujados los CheckBoxes
   End Sub








HdM

Hola.

Pero no estás haciendo i-1 en todos los casos en los que i actúa como índice.

Ej:

Código (vbnet) [Seleccionar]

Me.Panel1.Controls.Add(mCheck(i))
With mCheck(i)
                .Name = "Checkbox" & i
                .Text = folder.Name
                .Location = New Point(10, i * 20)
End With
AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox

- Nice to see you again -

kub0x

Nótese que actualizo la variable i y ReSizeo el Array al final del for, para que no tengas que cambiar nada.

Código (VB.NET) [Seleccionar]
   
' update checkboxes
    Public Sub updatecheckboxes()
        Dim filesystem = CreateObject("Scripting.FileSystemObject")
        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
        Dim i As Int32 = 0
        For Each folder In ThisDir.Subfolders
            mCheck(i) = New CheckBox()
            MessageBox.Show("test")
            Me.Panel1.Controls.Add(mCheck(i))
            With mCheck(i)
                .Name = "Checkbox" & i
                .Text = folder.Name
                .Location = New Point(10, i * 20)
            End With
            AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox
            i = i + 1
            Array.Resize(mCheck, i)
        Next
        CargarPropiedad()
    End Sub
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


Eleкtro

Cita de: HdM en 19 Noviembre 2012, 23:02 PM
Pero no estás haciendo i-1 en todos los casos en los que i actúa como índice.

Tienes razón, estoy un poco gilipo**** xD!

Lo he modificado correctamente (Eso creo) y por fin me funciona, muchisimas gracias

Pero los problemas sigueeeen!


Voy a poner un ejemplo visual:

se carga la app, pincho en el primer checkbox de todos, el "0", y cierro la app:




Vuelvo a abrir la app, y me aparece esto:




¿Serías tán amables de ayudarme a buscar el error en mi form?
(además, no se que coñ* he tocado para que el índice empieze con "checkbox0" y no con "checkbox1", ya me he mirado la variable "i" pero me ha parecido estar bien)


Código (vbnet) [Seleccionar]
Imports System.Windows.Forms
Imports System.IO

Public Class Form1
   Dim filesystem As Object, ThisDir As Object
   Dim mCheck(0) As CheckBox 'matriz que contendrá los "X" CheckBox

   ' Start of Propertys
   Public Property userSelectedPlayerFilePath() As String
       Get
           Return playertextbox.Text
       End Get
       Set(value As String)
           playertextbox.Text = value
       End Set
   End Property

   Public Property userSelectedFolderPath() As String
       Get
           Return foldertextbox.Text
       End Get
       Set(value As String)
           foldertextbox.Text = value
       End Set
   End Property

   Public Sub GenerarPropiedades() 'metodo que generará la propiedad al producirse el cierre del formulario
       Dim CheckedN As String = Nothing 'la cadena que contendrá los CheckBoxes que estén Checkados
       For i As Int32 = 0 To mCheck.Length - 1 'recorro la matriz de los CheckBoxes
           If mCheck(i).Checked = True Then 'Si el CheckBox actual está checkado
               CheckedN &= i + 1 'Obtengo su indice y lo meto al string (si es Checkbox1 pues 1, si es chckbx2 pues 2) ...
           End If
       Next
       My.Settings.CuantosChecked = CheckedN 'Actualizo la propiedad
       My.Settings.Save() 'Guardo la propiedad
   End Sub


   Public Sub CargarPropiedad() 'método que comprobará que CheckBoxes fueron tildados la útlima vez
       Dim mCuantosChecked As Char() = My.Settings.CuantosChecked.ToCharArray 'Paso el String de la propiedad a una matriz
       'Simplemente hago esto para separar el String por indices (un caracter por indice)
       For Each caracter As Char In mCuantosChecked 'Recorro la matriz caracteres que contendrá los checboxes tildados
           For Each CheckboxN In mCheck 'Recorro la matriz de CheckBoxes, para comparar si está o no está tildado
               If CheckboxN.Name.Contains(caracter) Then
                   'Si el CheckBox actual contiene cualquier caracter de la propiedad
                   'que tiene los indices de los CheckBoxes tildados
                   CheckboxN.Checked = True 'Lo tildo
               End If
           Next
       Next
   End Sub


   ' update checkboxes
   Public Sub updatecheckboxes()
       ' delete the old checkboxes
       Panel1.Controls.Clear()
       ' create the new checkboxes
       Dim filesystem = CreateObject("Scripting.FileSystemObject")
       Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
       Dim i As Int32 = 1
       'Dim mCheck() As CheckBox
       For Each folder In ThisDir.Subfolders

           'mCheck(i - 1) = New CheckBox()
           Array.Resize(mCheck, i)
           mCheck(i - 1) = New CheckBox()
           'MessageBox.Show("test")
           Me.Panel1.Controls.Add(mCheck(i - 1))
           With mCheck(i - 1)
               .Name = "Checkbox" & i - 1
               .Text = "Checkbox" & i - 1
               ' .Text = folder.Name
               .Location = New Point(10, i * 20)
           End With
           AddHandler mCheck(i - 1).CheckedChanged, AddressOf LlamadaCheckBox
           i = i + 1
       Next
       CargarPropiedad()
   End Sub

   ' Form close
   Public Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
       GenerarPropiedades()
       'My.Settings.Save()
   End Sub


   ' Form load
   Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
       playertextbox.Text = My.Settings.playerpath
       foldertextbox.Text = My.Settings.folderpath
       updatecheckboxes()
   End Sub


   ' Folder button
   Public Sub C1Button3_Click(sender As Object, e As EventArgs) Handles folderbutton.Click
       Dim folderselected As New System.Windows.Forms.FolderBrowserDialog
       Dim Resultado As DialogResult
       folderselected.RootFolder = Environment.SpecialFolder.Desktop
       Resultado = folderselected.ShowDialog
       If Resultado.ToString() = "OK" Then
           userSelectedFolderPath = folderselected.SelectedPath
           My.Settings.folderpath = folderselected.SelectedPath
           My.Settings.Save()
           updatecheckboxes()
       End If
   End Sub


   ' Player button
   Public Sub C1Button1_Click(sender As Object, e As EventArgs) Handles playerbutton.Click
       Dim playerselected As New OpenFileDialog()
       playerselected.InitialDirectory = Environ("programfiles")
       playerselected.Title = "Select your favorite music player"
       playerselected.Filter = "Music players|mpc.exe;mpc-hc.exe;mpc-hc64.exe;umplayer.exe;vlc.exe;winamp.exe;wmp.exe"
       PlayerDialog.FilterIndex = 1
       Dim selection As System.Windows.Forms.DialogResult = playerselected.ShowDialog()
       If selection = DialogResult.OK Then
           userSelectedPlayerFilePath = playerselected.FileName
           My.Settings.playerpath = playerselected.FileName
           My.Settings.Save()
       End If
   End Sub


   ' Play button
   Public Sub C1Button2_Click(sender As Object, e As EventArgs) Handles C1Button2.Click
       'Process.Start(userSelectedPlayerFilePath, ControlChars.Quote & Path.Combine(ThisDir.Path, checkedpath1) & ControlChars.Quote)
   End Sub



   ' función que se ejecuta cuando cualquier checkbox es clickado
   Public Sub LlamadaCheckBox(ByVal sender As Object, ByVal e As System.EventArgs)
       Dim CheckboxN As CheckBox = CType(sender, CheckBox) 'a partir del sender creo el CheckBox (paso de objet a CheckBox para poder utilizar sus propiedades)
       'MsgBox(CheckboxN.Name)

   End Sub

End Class








kub0x

Código (VB.NET) [Seleccionar]
' update checkboxes
   Public Sub updatecheckboxes()
       Dim filesystem = CreateObject("Scripting.FileSystemObject")
       Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
       Dim i As Int32 = 0
       For Each folder In ThisDir.Subfolders
           mCheck(i) = New CheckBox()
           MessageBox.Show("test")
           Me.Panel1.Controls.Add(mCheck(i))
           With mCheck(i)
               .Name = "Checkbox" & i +1 'De esta forma sumas 1 y tendrás CheckBox1,2,3
               .Text = "CheckBox" & i+1 'Lo mismo para el nombre
               .Location = New Point(10, i * 20)
           End With
           AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox
           i = i + 1
           Array.Resize(mCheck, i)
       Next
       CargarPropiedad()
   End Sub
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


Eleкtro

No Kubox, he usado ahora mismo tu ejemplo y solo se muestra UN checkbox:



Te lo agradezco de todas formas, a ver si doy con el fallo..








kub0x

El fallo está en que tu escribes CheckBox0 y cuando cargas las propiedades esperas un CheckBox1,2,3,4 no el 0 xD
Para ello cuando generes los CheckBoxes empieza desde i=0, suma i+1 a la propiedad .Name y .Text de los CheckBoxes y y al final del for suma 1 como te dije, para ReSizear el Array, a mí me funciona :S
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


HdM

Con respecto al otro error, el de que te aparezcan seleccionados "automáticamente" a partir del 10 cuando abres de nuevo la app; es debido a:

Código (vbnet) [Seleccionar]

For Each CheckboxN In mCheck 'Recorro la matriz de CheckBoxes, para comparar si está o no está tildado
                If CheckboxN.Name.Contains(caracter) Then
                    'Si el CheckBox actual contiene cualquier caracter de la propiedad
                    'que tiene los indices de los CheckBoxes tildados
                    CheckboxN.Checked = True 'Lo tildo
                End If
Next


Ese Contains, si seleccionas el checkbox 1, siempre lo va a contener y te seleccionará todos los checks que contengan 1 (1,11,12,13,...,21,31,...), si seleccionas el 2, pues todos los que contengan ese número,...

Como alternativa, podrías almacenar en un array numérico de enteros.

Saludos.

- Nice to see you again -

Eleкtro

#28
Cita de: kub0x en 19 Noviembre 2012, 23:29 PM
Para ello cuando generes los CheckBoxes empieza desde i=0, suma i+1 a la propiedad .Name y .Text de los CheckBoxes y y al final del for suma 1 como te dije, para ReSizear el Array, a mí me funciona :S

¿Eso es lo que hace tu última modificación de mi ejemplo, verdad?
Pues lo he copiado tál cual y no me funciona.

Mañana me lo miro con calma y sigo con el tema si aún no he podido resolverlo,

Aquí, y en stackoverf*** teneis que estar ya hartos de mí :xD, pero estais ayudando a alguien a aprender cosas nuevas de VB.NET, métodos nuevos, objetos nuevos, y en resumen aprender a hacer las cosas bien.

Como me dijo todo un experto en .NET, solo hay que saber "mezclar" las cosas bien.

Un saludo

PD: Hdm, lo mismo digo, mañana me lo miro detalladamente, y gracias.


EDITO: Por cierto, quizás es una tontería pero... ¿sería posible usar un regexp en "caracter"?

f CheckboxN.Name.Contains(caracter) Then

no se hacerlo en VB pero sería otra posibilidad (más sencilla para mí)
saludos








Keyen Night

que buscarias capturar con la expresion regular?
La Fé Mueve Montañas...
                                    ...De Dinero

La programación es más que un trabajo es más que un hobby es una pasión...