Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: Eleкtro en 18 Noviembre 2012, 12:39 pm



Título: (solucionado) ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 18 Noviembre 2012, 12:39 pm
Hola,

Tengo un panel con casi 50 checkboxes (todos siguen un orden de nombre bien enumerado), y por ejemplo este es el sub del chekbox1:

Código
  1.    Public Sub C1CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles C1CheckBox1.CheckedChanged
  2.        If C1CheckBox1.Checked = True Then My.Settings.box1_selected = "Y" Else My.Settings.box1_selected = "N"
  3.        Dim checkedpath1 = C1CheckBox1.Text
  4.    End Sub

Lo que quisiera poder hacer es que ese mismo evento afecte a todos los checkboxes, eso se que se puede hacer añadiendo los checkboxes al "handle", vale, pero no es suficiente, ya que lo que hay dentro del sub del ejemplo solo afectará al checkbox 1 aunque yo añada todos al handle, ¿entienden lo que quiero decir?

Hay alguna forma de no escribir el mismo evento para los 50 checkboxes?

es decir, yo necesito hacer esto:

(Pseudocode)

Public Sub TODOS_LOS_CHECKBOXES_CheckedChanged(sender As Object, e As EventArgs) Handles TODOS_LOS_CHECKBOXES.CheckedChanged
If CUALQUIER_CHECKBOX.Checked = True Then My.Settings.NÚMERO_DEL_CHECKBOX_SELECCIONADO_selected = "Y" Else My.Settings.boxNÚMERO_DEL_CHECKBOX_SELECCIONADO_selected = "N"
Dim checkedpathNÚMERO_DEL_CHECKBOX _SELECCIONADO = C1CheckBoxNÚMERO_DEL_CHECKBOX _SELECCIONADO.Text
End Sub


Gracias y un saludo...


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Danyfirex en 18 Noviembre 2012, 13:49 pm
Si pones tus checkboxs en un groupbox puedes hacer esto.

Código
  1. Dim ChkBox As CheckBox = Nothing
  2.  
  3.        For Each xObject As Object In Me.GroupBox1.Controls
  4.            If TypeOf xObject Is CheckBox Then
  5.                ChkBox = xObject
  6.                ChkBox.Checked = True
  7.            End If
  8.        Next


creo que a eso te refieres.

y sin Groupbox así:

Código
  1. For Each ctrl As Control In Me.Controls
  2.  
  3.            If TypeOf ctrl Is CheckBox Then
  4.                DirectCast(ctrl, CheckBox).CheckState = CheckState.Checked
  5.            End If
  6.  
  7.        Next

saludos.


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 18 Noviembre 2012, 17:33 pm
Hola,

Gracias, pero lo he probado sin groupbox y no sé como hacerlo funcionar, directamente no ocurre nada... (no me da error)

Código
  1.      For Each ctrl As Control In Me.Controls
  2.            If TypeOf ctrl Is CheckBox Then
  3.                DirectCast(ctrl, CheckBox).Text = "Test"
  4.            End If
  5.        Next

EDITO: Aún así, ese código tendría que usarlo en algun evento... y yo lo que necesito es un evento que haga eso para todos los checkboxes... así que en que evento lo meto? xD

que hago mal?


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 18 Noviembre 2012, 20:41 pm
Lo que buscas es que todos los CheckBox al ser clickados llamen a un mismo método. Con el "Handles" logras que las acciones de el método trabajen con el objeto que va con el "Handles", no con todos los objetos del mismo tipo.

Este ejemplo crea 3 CheckBox dinámicamente y los agrega al Formulario, sin haberlos dibujado con el IDE del Visual Basic. Después asocio a cada evento CheckedChange del Checkbox con la funcion "LlamadaCheckBox", donde se ejecutarán las instrucciones que desees. Es decir, todos los eventos CheckedChanged de tus CheckBox se asociarán a dicho método, y al producirse tal evento pues se llamará a dicha función.

Código
  1. Public Class Form1
  2.  
  3. ' Esta es la función que se llamará al producirse el evento CheckedChange del CheckBox
  4.    Private Sub LlamadaCheckBox(ByVal sender As Object, ByVal e As System.EventArgs)
  5.        Dim CheckboxN As CheckBox = CType(sender, CheckBox) 'a partir del sender creo el CheckBox (paso de objet a CheckBox para poder utilizar sus propiedades)
  6.        msgbox("Me pinchaste, la cagaste xD")
  7.    End Sub
  8.  
  9.    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  10.        Dim mCheck(2) As CheckBox 'matriz que contendrá los 3 CheckBox
  11.        For i As Int32 = 0 To mCheck.Length - 1
  12.            mCheck(i) = New CheckBox() 'creo un CheckBox en cada espacio de la matriz
  13.            With mCheck(i)
  14.                .Text = "Checkbox" & i + 1 ' Le adjunto un nombre Checkbox1 / Checkbox2 y 3
  15.                .Location = New Point(20, i * 30) ' Sin más los situo....
  16.            End With
  17.            AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox'Asocio el evento CheckedChange del CheckBox actual a la función LlamadaCheckBox
  18.            Me.Controls.Add(mCheck(i)) 'Añado el control al formulario, es decir, lo dibujo
  19.        Next
  20.    End Sub
  21. End Class
  22.  

Espero haberte servido de ayuda!

Saludos!


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: criskapunk en 18 Noviembre 2012, 21:07 pm
No se si te será de ayuda, pero no se podría crear una matriz de controles en los que por cada elemento (las checkboxes) se vaya realizando la misma rutina?

:http://www.elguille.info/NET/dotnet/arrayControles.htm

Un saludo.


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 18 Noviembre 2012, 22:38 pm

Espero haberte servido de ayuda!

Saludos!

Increible, muchísimas gracias Kubox

Mi intención era que al cargar la app saliesen 1 textbox por cada X carpeta previamente bindeada, y he conseguido "dibujar" los textboxs hace unos minutos así:

Código
  1.  Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  2.        playertextbox.Text = My.Settings.playerpath
  3.        foldertextbox.Text = My.Settings.folderpath
  4.        updatefoldernames()
  5.    End Sub
  6.  
  7.    Public Sub updatefoldernames()
  8.        Dim List As Integer = 0
  9.        Dim posy As Integer = 10
  10.  
  11.        filesystem = CreateObject("Scripting.FileSystemObject")
  12.        ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  13.  
  14.        For Each folder In ThisDir.Subfolders
  15.            List = List + 1
  16.            posy = posy + 20
  17.            Dim newCheckBox As New CheckBox()
  18.            Panel1.Controls.Add(newCheckBox)
  19.            newCheckBox.Name = "checkbox" & List.ToString()
  20.            newCheckBox.Text = folder.name
  21.            newCheckBox.Location = New Point(10, posy)
  22.            'MessageBox.Show(newCheckBox.Name.ToString())
  23.  
  24.            Dim checkbox_selected As String = "checkbox" & List.ToString()
  25.            If My.Settings.checkbox_selected = "Y" Then newCheckBox.Checked = True
  26.        Next
  27.    End Sub

Pero me tendría que haber comido la cabeza unas semanas para conseguir lo del evento... ja!, addhandler!, como para saberlo sin haber estudiado 1 año mínimo xD, mil gracias esto me ahorra mucho trabajo ^^

EDITO: Aprovecho para preguntarte Kubox, si puedes fijarte en el final de ese code, intento asociar cada checkbox al nombre de "my.settings"

En my.settings lo tengo así:
My.Settings.checkbox1
My.Settings.checkbox2
My.Settings.checkbox3
etc...
Pero no consigo llamar a ninguno porque solo me acepta un string así que esto me da error:  My.Settings.checkbox_selected

un saludo


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 19 Noviembre 2012, 08:47 am
Aupa EleKtro H@cker,

buscas cambiar el valor de alguna propiedad guardada en my.settings o simplemente hacer comprobaciones con éstas? Sería mejor que fueras más claro : p

Ahora estoy en clase y no puedo echarle una buena ojeada, más tarde estaré disponible.

Espero tu respuesta,

Saludos!


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 19 Noviembre 2012, 14:13 pm
buscas cambiar el valor de alguna propiedad guardada en my.settings o simplemente hacer comprobaciones con éstas? Sería mejor que fueras más claro : p

Verás, pienso usar el ejemplo que me has proporcionado, eso sin duda, pero esto lo necesito hacer tanto para tu ejemplo como para el mío



En mi ejemplo de arriba, creo nuevos checkboxes y les proporciono un nombre:
Código:
newCheckBox.Name = "checkbox" & List.ToString()

El nombre final de cada checkbox es: "checkbox1", "checkbox2", "checkbox3", etc...

En my-settings los nombres que tengo son:
checkbox1
checkbox2
checkbox3
etc...

(Cada uno con el scope "user", y con el valor de "Y" o "N".)

En resumen, los nombres de los nuevos checkboxes y los nombres de my.settings son exactamente igual, eso lo hice para poder referenciarme mejor a "my.settings" basandome en el nombre de los nuevos checkboxes, pero no lo he conseguido xD.

Por ejemplo:

Código
  1. Panel1.Controls.Add(newCheckBox)
  2. newCheckBox.Name = "checkbox" & List.ToString()

Eso se llamará checkbox1, pues quisiera crear una nueva entrada (o reemplazar una ya existente con el mismo nombre) en my.settings, que tenga el mismo nombre que el "checkbox.Name", y poder obetener el valor de esa entrada.

Osea, crear la entrada "checkbox1" en my.settings, y obtener el valor de "checkbox1" en my-settings, las dos cosas necesitaría,pero sobretodo obtener el valor...

Yo se obtener y guardar valores en my.settings, pero no se hacerlo cuando el nombre que le intento dar al "my.settings" es el objeto "newCheckBox.Name = "checkbox" & List.ToString()"
Si uso "My.settings.newCheckBox.Name" me dice que no es un string, con toda la razón xD.

Muchas gracias por tu tiempo Kubox!




Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 19 Noviembre 2012, 16:34 pm
Ya he acoplado tu code a mi form, muchas gracias de nuevo

Lo que intento hacer es guardar en las settings los checkboxes que están clickados antes de cerrar el form:

Código
  1.    ' función que se ejecuta cuando cualquier checkbox es clickado
  2.    Public Sub LlamadaCheckBox(ByVal sender As Object, ByVal e As System.EventArgs)
  3.        Dim CheckboxN As CheckBox = CType(sender, CheckBox) 'a partir del sender creo el CheckBox (paso de objet a CheckBox para poder utilizar sus propiedades)
  4.        MsgBox(CheckboxN.Name)
  5.        If CheckboxN.Checked = True Then My.Settings.Selected_Checkboxes.Add(CheckboxN.Name.ToString())
  6.    End Sub

pero me dice: Object reference not set to an instance of an object.

La setting la tengo como tipo: "system.collection.specialized.stringcollection", no se si es la correcta.



Una vez conseguido eso, al volver a abrir la app (el form) necesitaría averiguar cuales checkboxes estaban clickados para seleccionarlos automáticamente


ojalá puedas ayudarme con eso


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 19 Noviembre 2012, 17:00 pm
Una vez conseguido eso, al volver a abrir la app (el form) necesitaría averiguar cuales checkboxes estaban clickados para seleccionarlos automáticamente

En ese momento deberias cargar las propiedades e ir comparando uno a uno los valores de las propiedades y si esta en True (Clickado) pues activar la propiedad Checked del CheckBox. Es decir, PropiedadCheckBox1 -> ¿True? -> Sí -> Activar CheckBox1 .. saltar ala siguiente propiedad.

No he probado el código, hace mil que no utilizo propieadades de forma dinámica (on the fly) pero bueno, este código lo que hace es generar X propiedades por cada X CheckBoxes que haya en una matriz mCheckBox (lo de la matriz lo puedes cambiar recorriendo por ejemplo los controles del Panel donde estén los CheckBox)

Código
  1.    Private Sub GenerarPropiedades(ByVal mCheckBox As CheckBox())
  2.        For Each checkboxN As CheckBox In mCheckBox 'por cada CheckBox en mCheckBox
  3. 'Creo una propiedad con el nombre del CheckBox
  4. 'De esta forma cada CheckBox tendrá una propiedad equivalente
  5.            My.Settings.Properties.Add(New Configuration.SettingsProperty(checkboxN.Name))
  6. 'Meto el valor de la propiedad Checked en la nueva propiedad que hemos creado para el CheckBox
  7.            My.Settings.Properties.Item("CheckBox").DefaultValue = checkboxN.Checked
  8.        Next
  9.        My.Settings.Save()
  10.    End Sub
  11.  

Gracias por tu atención :)

Si necesitas ayuda para el siguiente caso (Cargar los CheckBoxes tildados mediante las propiedades) avisa.

Saludos!


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 19 Noviembre 2012, 17:03 pm
Uhm como solo te interesan los CheckBoxes tildados (Checked = TRUE) pues ponle un condicional para que sólo guarde éstos últimos.

Ya me cuentas ;)



Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 19 Noviembre 2012, 17:11 pm
Gracias,

una pregunta tonta.... ¿Como coñ* lo utilizo? ¿Que tipo de argumento "mCheckBox" debo pasarle al sub? xD

Aparte, me da este error en "Configuration.SettingsProperty":

Cita de: VS
Error   1   'Configuration' is ambiguous, imported from the namespaces or types 'System, System.Drawing'.



EDITO:
Alguien me ha proporcionado este code en otro sitio, pero por más que lo intento no sé como utilizarlo:

Código
  1. Public Sub AnyCB_CheckedChanged(sender As Object, e As EventArgs)
  2.  
  3.        Dim cb = DirectCast(sender, CheckBox)
  4.        If cb.Checked AndAlso Not My.Settings.MyCBs.Contains(cb.Name) Then
  5.            My.Settings.MyCBs.Add(cb.Name)
  6.        ElseIf Not cb.Checked AndAlso My.Settings.MyCBs.Contains(cb.Name) Then
  7.            My.Settings.MyCBs.Remove(cb.Name)
  8.        End If
  9.  
  10.    End Sub
  11.  
  12.    Public Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
  13.  
  14.        If My.Settings.MyCBs Is Nothing Then My.Settings.MyCBs = New Collections.Specialized.StringCollection
  15.  
  16.        For Each s In My.Settings.MyCBs
  17.            DirectCast(Me.Controls(s), CheckBox).Checked = True
  18.        Next
  19.  
  20.        For Each cb In Me.Controls.OfType(Of CheckBox)()
  21.            AddHandler cb.CheckedChanged, AddressOf AnyCB_CheckedChanged
  22.        Next
  23.  
  24.    End Sub
Cuando clicko en un checkbox este no se guarda en "my.settings" así que cuando vuelvo a abrir la app, el checkbox no se auto-selecciona.

PD: Tengo creada la entrada "MyCBs" de tipo "Collections.Specialized.StringCollection" en "my.settings"


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 19 Noviembre 2012, 18:47 pm
Joder que comedero de cabeza xD todo para encontrar que una vez generado el archivo Settings no se puede agregar configuraciones desde el código, como el tuyo de arriba o el que te había posteado (que ya lo corregí, pero no cargaba las configs). Para agregarlas tendrías que hacerlo dinámicamente, es decir, sobre el fichero de configuraciones, pues ya sea mediante serialización para convertir dichos valores de las propiedades a XML.

Se me ocurre que podrías hacer trampa en esto, es decir, creas una propiedad "CuantosChecked" donde añadiras los controles que están checkados. Pues si tienes el Checkbox2 el 5 y el 6 checkados la cadena que le pasarás a esa propiedad quedará así -> 256. Luego en el inicio de la app obtienes todos los CheckBox y obtienes un índice de dicha cadena. Si el CheckBox que has obtenido contiene el elemento del indice de la cadena (If checkbox2.contains(2) entonces lo checkas). Vamos, esto lo llevaba pensando tiempo ya, pero estaba intentando encontrar la forma limpia de implementarlo.

Te dejo un ejemplo. Funciona 100%, eso sí cualquier error ya sabes.

Código
  1. Public Class Form1
  2.  
  3.    Dim mCheck(5) As CheckBox 'matriz que contendrá los 5 CheckBox
  4.  
  5.    Private Sub GenerarPropiedades() 'metodo que generará la propiedad al producirse el cierre del formulario
  6.        Dim CheckedN As String = Nothing 'la cadena que contendrá los CheckBoxes que estén Checkados
  7.        For i As Int32 = 0 To mCheck.Length - 1 'recorro la matriz de los CheckBoxes
  8.            If mCheck(i).Checked = True Then 'Si el CheckBox actual está checkado
  9.                CheckedN &= i + 1 'Obtengo su indice y lo meto al string (si es Checkbox1 pues 1, si es chckbx2 pues 2) ...
  10.            End If
  11.        Next
  12.        My.Settings.CuantosChecked = CheckedN 'Actualizo la propiedad
  13.        My.Settings.Save() 'Guardo la propiedad
  14.    End Sub
  15.    Private Sub CargarPropiedad() 'método que comprobará que CheckBoxes fueron tildados la útlima vez
  16.        Dim mCuantosChecked As Char() = My.Settings.CuantosChecked.ToCharArray 'Paso el String de la propiedad a una matriz
  17.        'Simplemente hago esto para separar el String por indices (un caracter por indice)
  18.        For Each caracter As Char In mCuantosChecked 'Recorro la matriz caracteres que contendrá los checboxes tildados
  19.            For Each CheckboxN In mCheck 'Recorro la matriz de CheckBoxes, para comparar si está o no está tildado
  20.                If CheckboxN.Name.Contains(caracter) Then
  21.                    'Si el CheckBox actual contiene cualquier caracter de la propiedad
  22.                    'que tiene los indices de los CheckBoxes tildados
  23.                    CheckboxN.Checked = True 'Lo tildo
  24.                End If
  25.            Next
  26.        Next
  27.    End Sub
  28.    Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
  29.        'Este es el evento al que se llamará cuando se cierre la aplicación
  30.        'Como ves al cerrar la aplicación llamamos al método GenerarPropiedades() para guardar los CheckBoxes que fueron tildados
  31.        GenerarPropiedades()
  32.    End Sub
  33.    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  34.        For i As Int32 = 0 To mCheck.Length - 1
  35.            mCheck(i) = New CheckBox() 'creo un CheckBox en cada espacio de la matriz
  36.            With mCheck(i)
  37.                .Text = "Checkbox" & i + 1 ' Le adjunto un nombre Checkbox1 / Checkbox2 y 3
  38.                .Location = New Point(20, i * 30) ' Sin más los situo....
  39.                .Name = "Checkbox" & i + 1
  40.            End With
  41.            Me.Controls.Add(mCheck(i)) 'Añado el control al formulario, es decir, lo dibujo
  42.        Next
  43.        CargarPropiedad() 'Cargo las propiedades una vez dibujados los CheckBoxes
  44.    End Sub
  45. End Class
  46.  

Saludos!


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 19 Noviembre 2012, 19:12 pm
Tu ejemplo me funciona perfectamente en un winform nuevo, pero cuando intento acoplarlo a mi winform ocurre una cosa... EL FORM NO SE CIERRA AL PULSAR EL BOTON DE CERRAR :  :huh: :huh: :huh:

Te lo agradezco mucho, ya me has ayudado bastante, pero ahora no se como "salir" de aquí, y como no puedo cerrarlo tampoco puedo saber si se guardan correctamente en my.settings xD

Te pongo mi form COMPLETO por si sabes donde puede estar mi error:

PD: uso Dim mCheck(9999) porque la cantidad de checkboxes a agregar es indeterminada, se agrega un checkbox nuevo en el form por cada carpeta de una ruta previamente cargada, no se si puedo hacerlo de mejor manera eso...

Código
  1. Imports System.Windows.Forms
  2. Imports System.IO
  3.  
  4. Public Class Form1
  5.    Dim filesystem As Object, ThisDir As Object
  6.    Public newCheckBox As New CheckBox()
  7.    Dim mCheck(9999) As CheckBox 'matriz que contendrá los "X" CheckBox
  8.  
  9.    ' Start of Propertys
  10.    Public Property userSelectedPlayerFilePath() As String
  11.        Get
  12.            Return playertextbox.Text
  13.        End Get
  14.        Set(value As String)
  15.            playertextbox.Text = value
  16.        End Set
  17.    End Property
  18.  
  19.    Public Property userSelectedFolderPath() As String
  20.        Get
  21.            Return foldertextbox.Text
  22.        End Get
  23.        Set(value As String)
  24.            foldertextbox.Text = value
  25.        End Set
  26.    End Property
  27.  
  28.    Public Property checkedpath1() As String
  29.        Get
  30.            Return newCheckBox.Text
  31.        End Get
  32.        Set(value As String)
  33.            newCheckBox.Text = value
  34.        End Set
  35.    End Property
  36.    ' End of propertys
  37.  
  38.  
  39.    ' update checkboxes
  40.    Public Sub updatecheckboxes()
  41.        ' delete the old checkboxes
  42.        Panel1.Controls.Clear()
  43.        ' create the new checkboxes
  44.        Dim i As Int32 = 0
  45.        Dim posy As Integer = 0
  46.        Dim filesystem = CreateObject("Scripting.FileSystemObject")
  47.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  48.        For Each folder In ThisDir.Subfolders
  49.            i = i + 1
  50.            mCheck(i) = New CheckBox() 'creo un CheckBox en cada espacio de la matriz
  51.            With mCheck(i)
  52.                .Name = "Checkbox" & i ' Le adjunto un nombre Checkbox1 / Checkbox2 y 3
  53.                .Text = folder.name
  54.                .Location = New Point(10, i * 20)
  55.            End With
  56.            'MessageBox.Show(mCheck(i).Name)
  57.            AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox 'Asocio el evento CheckedChange del CheckBox actual a la función LlamadaCheckBox
  58.            Panel1.Controls.Add(mCheck(i))
  59.        Next
  60.        CargarPropiedad() 'Cargo las propiedades una vez dibujados los CheckBoxes
  61.    End Sub
  62.  
  63.  
  64.    Public Sub CargarPropiedad() 'método que comprobará que CheckBoxes fueron tildados la útlima vez
  65.        Dim mCuantosChecked As Char() = My.Settings.CuantosChecked.ToCharArray 'Paso el String de la propiedad a una matriz
  66.        'Simplemente hago esto para separar el String por indices (un caracter por indice)
  67.        For Each caracter As Char In mCuantosChecked 'Recorro la matriz caracteres que contendrá los checboxes tildados
  68.            For Each CheckboxN In mCheck 'Recorro la matriz de CheckBoxes, para comparar si está o no está tildado
  69.                If CheckboxN.Name.Contains(caracter) Then
  70.                    'Si el CheckBox actual contiene cualquier caracter de la propiedad
  71.                    'que tiene los indices de los CheckBoxes tildados
  72.                    CheckboxN.Checked = True 'Lo tildo
  73.                End If
  74.            Next
  75.        Next
  76.    End Sub
  77.  
  78.  
  79.    Private Sub GenerarPropiedades() 'metodo que generará la propiedad al producirse el cierre del formulario
  80.        Dim CheckedN As String = Nothing 'la cadena que contendrá los CheckBoxes que estén Checkados
  81.        For i As Int32 = 0 To mCheck.Length - 1 'recorro la matriz de los CheckBoxes
  82.            If mCheck(i).Checked = True Then 'Si el CheckBox actual está checkado
  83.                CheckedN &= i + 1 'Obtengo su indice y lo meto al string (si es Checkbox1 pues 1, si es chckbx2 pues 2) ...
  84.            End If
  85.            Me.Close()
  86.        Next
  87.  
  88.        My.Settings.CuantosChecked = CheckedN 'Actualizo la propiedad
  89.        My.Settings.Save() 'Guardo la propiedad
  90.  
  91.    End Sub
  92.  
  93.  
  94.    ' Form close
  95.    Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
  96.        'Este es el evento al que se llamará cuando se cierre la aplicación
  97.        'Como ves al cerrar la aplicación llamamos al método GenerarPropiedades() para guardar los CheckBoxes que fueron tildados
  98.        '      My.Settings.Save()
  99.        GenerarPropiedades()
  100.        Me.Close()
  101.    End Sub
  102.  
  103.  
  104.    ' Form load
  105.    Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  106.        playertextbox.Text = My.Settings.playerpath
  107.        foldertextbox.Text = My.Settings.folderpath
  108.        updatecheckboxes()
  109.        CargarPropiedad() 'Cargo las propiedades una vez dibujados los CheckBoxes
  110.    End Sub
  111.  
  112.    ' Folder button
  113.    Private Sub C1Button3_Click(sender As Object, e As EventArgs) Handles folderbutton.Click
  114.        Dim folderselected As New System.Windows.Forms.FolderBrowserDialog
  115.        Dim Resultado As DialogResult
  116.        folderselected.RootFolder = Environment.SpecialFolder.Desktop
  117.        Resultado = folderselected.ShowDialog
  118.        If Resultado.ToString() = "OK" Then
  119.            userSelectedFolderPath = folderselected.SelectedPath
  120.            My.Settings.folderpath = folderselected.SelectedPath
  121.            My.Settings.Save()
  122.            updatecheckboxes()
  123.        End If
  124.    End Sub
  125.  
  126.  
  127.    ' Player button
  128.    Public Sub C1Button1_Click(sender As Object, e As EventArgs) Handles playerbutton.Click
  129.        Dim playerselected As New OpenFileDialog()
  130.        playerselected.InitialDirectory = Environ("programfiles")
  131.        playerselected.Title = "Select your favorite music player"
  132.        playerselected.Filter = "Music players|mpc.exe;mpc-hc.exe;mpc-hc64.exe;umplayer.exe;vlc.exe;winamp.exe;wmp.exe"
  133.        PlayerDialog.FilterIndex = 1
  134.        Dim selection As System.Windows.Forms.DialogResult = playerselected.ShowDialog()
  135.        If selection = DialogResult.OK Then
  136.            userSelectedPlayerFilePath = playerselected.FileName
  137.            My.Settings.playerpath = playerselected.FileName
  138.            My.Settings.Save()
  139.        End If
  140.    End Sub
  141.  
  142.  
  143.    ' Play button
  144.    Public Sub C1Button2_Click(sender As Object, e As EventArgs) Handles C1Button2.Click
  145.        Process.Start(userSelectedPlayerFilePath, ControlChars.Quote & Path.Combine(ThisDir.Path, checkedpath1) & ControlChars.Quote)
  146.    End Sub
  147.  
  148.    ' función que se ejecuta cuando cualquier checkbox es clickado
  149.    Public Sub LlamadaCheckBox(ByVal sender As Object, ByVal e As System.EventArgs)
  150.        Dim CheckboxN As CheckBox = CType(sender, CheckBox) 'a partir del sender creo el CheckBox (paso de objet a CheckBox para poder utilizar sus propiedades)
  151.        MsgBox(CheckboxN.Name)
  152.  
  153.    End Sub
  154.  
  155.  
  156.  
  157. End Class
  158.  
  159.  


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 19 Noviembre 2012, 19:26 pm
PD: uso Dim mCheck(9999) porque la cantidad de checkboxes a agregar es indeterminada, se agrega un checkbox nuevo en el form por cada carpeta de una ruta previamente cargada, no se si puedo hacerlo de mejor manera eso...

Se me ocurre sumarr un indíce a dicha matriz mCheck por cada carpeta encontrada, es decir, Resizeas la matriz por cada indice.

Código
  1. Dim mCheck(0) as CheckBox() 'un indice
  2.  
  3. Private Sub BuscarCarpetas()
  4. Dim i as integer = 0
  5. for directorio in subdirectorios
  6. i+=1 'se encontró una carpeta, sumo un indice
  7. Array.Resize(mCheck,i) 'meto un indice mas a la matriz de CheckBoxes
  8. for i as int32 = 0 to mCheck.length - 1
  9. mCheck(i) = New CheckBox()
  10. 'y aqui sigues como esta
  11. Next
  12.  

De esta forma sólo creas los CheckBoxes que tú necesites basándote en las carpetas encontradas en un directorio. En cuanto al no poder controlar el evento de cierre, ¿Has probado metiéndole un Breakpoint o un MsgBox() para ver si se llama? ¿Has probado a utilizar el evento FormClosed en vez de FormClosing? ¿Probaste quitándole el Me.Formclosing y poniéndole MyBase.Formclosing? Ésto último no tiene mucho que ver xD pero ya sabes, la vida es rara.

No he detectado ninguna anomalía a simple vista, solo que no utilizas una variable y que Dim filesystem = CreateObject("Scripting.FileSystemObject") sobra porque hay una clase del Framework que nos permite trabajar de la misma forma (FileIO creo que era).

Saludos!


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 19 Noviembre 2012, 19:56 pm
Pero entonces donde pone ".Text = folder.Name", ¿como puedo hacerlo?

¿Debo crear una lista que contenga cada nombre de carpeta en un string para luego usarlo en la propiedad "text" del segundo FOR? puf...

¿No se puede hacer esto en un solo bucle?
Código
  1.       Dim filesystem = CreateObject("Scripting.FileSystemObject")
  2.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  3.        Dim folderindex As Integer = 0
  4.  
  5.        For Each folder In ThisDir.Subfolders
  6.            folderindex += 1
  7.            Array.Resize(mCheck, folderindex)
  8.        Next
  9.  
  10.        For i As Int32 = 0 To mCheck.Length - 1
  11.            mCheck(i) = New CheckBox()
  12.            With mCheck(i)
  13.                .Name = "Checkbox" & i
  14.                .Text = folder.Name
  15.                .Location = New Point(10, i * 20)
  16.            End With
  17.        Next

PD: Da error en ".Text = folder.Name" obviamente porque nada tiene que ver, pero no se como hacerlo.


EDITO: He conseguido "salir" de la app cambiando esto:

Código
  1. Dim mCheck(5) As CheckBox 'matriz que contendrá los "X" CheckBox
(Si el número 5 es mayor que las "carpetas" en total, osea, los checkboxes añadidos al cargarse el form, entonces sigue sin poderse cerrar)
(Vamos, que si en la app se cargan 20 checkboxes pues debería poner mcheck(19) manualmente para poder cerrar el form)

Código
  1. For i As Int32 = 1 To mCheck.Length - 1 'recorro la matriz de los CheckBoxes
Además de cambiar lo de antes, debo cambiar el valor inicial de 0, a 1, ¿algo raro pasa con el índice no?

Lo bueno viene ahora, puedo cerrar el form pero las propiedades no se me guardan!, bueno, yo que sé si se guardan, pero cuando vuelvo a abrir la app la casilla que estaba seleccionada no se selecciona...

En resumen, creo que la solución está arreglando el code de la forma que me has intnetado explicar Kubox, añadiendo un índice por cada carpeta encontrada, porque sinó no puedo salir del form ni tampoco se me guardan las settings arreglando el problema de "salir"  :xD.


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 19 Noviembre 2012, 21:03 pm
Perdona que haya tardado en contestar. Como yo te decia antes, tienes que cambiar el indice de la matriz de los CheckBoxes en función de las carpetas encontradas. Lo puedes hacer en un mismo For todo xD

Es decir,

For subdirectorios en Directorios
i += 1
Array.resize(matrizCheckBox,i)
.......
matrizCheckBox(i) = new Checkbox
.......
Next

De esta forma compruebas las carpetas, obtienes indices y generas CheckBox, todo en uno.

¿Por que dices que los indices están mal? Espero que te sirva de ayuda lo que te he dicho =p


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 19 Noviembre 2012, 21:20 pm
Nada, tu contesta cuando puedas y solamente si te apetece, sinó mandame a buscarme la vida por ahí xD

¿Me puedes decir si está bien el For?
Bueno, no está bien, porque al cargar el form no se muestra NINGUN checkbox

Código
  1.    ' update checkboxes
  2.    Public Sub updatecheckboxes()
  3.        ' delete the old checkboxes
  4.        Panel1.Controls.Clear()
  5.        ' create the new checkboxes
  6.        Dim filesystem = CreateObject("Scripting.FileSystemObject")
  7.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  8.        Dim i As Int32 = 0
  9.        For Each folder In ThisDir.Subfolders
  10.            i += 1
  11.            Array.Resize(mCheck, i)
  12.            MessageBox.Show("test")
  13.            mCheck(i) = New CheckBox()
  14.            With mCheck(i)
  15.                .Name = "Checkbox" & i
  16.                .Text = folder.Name
  17.                .Location = New Point(10, i * 20)
  18.            End With
  19.            AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox 'Asocio el evento CheckedChange del CheckBox actual a la función LlamadaCheckBox
  20.            Panel1.Controls.Add(mCheck(i))
  21.        Next
  22.        CargarPropiedad() 'Cargo las propiedades una vez dibujados los CheckBoxes
  23.    End Sub

Tengo declarado el mcheck así como me dijiste:
Código:
  Dim mCheck(0) As CheckBox

PD: El messagebox solo se muesta UNA vez :S
Muchas gracias por tu tiempo


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: HdM en 19 Noviembre 2012, 22:25 pm
Hola EleKtro.

El problema lo tienes aquí:

Código
  1.       'al incrementar la variable i, no estas inicializando el 1er elemento del array (indice=0)
  2.       i += 1
  3.       Array.Resize(mCheck, i)
  4.       MessageBox.Show("test")
  5.       mCheck(i) = New CheckBox()
  6.        With mCheck(i)

Prueba poniendo todas las referencias a i cuando actúa como índice dentro del bucle, como i-1.

Saludos.


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 19 Noviembre 2012, 22:33 pm
HdM tiene razón. El error reside en que en el caso mCheck(0) no le estás instanciando ningun objeto CheckBox. Entonces dentro del bucle For, para instanciar los CheckBoxes en mCheck tendrás que hacerlo así:

mCheck(i-1) = New CheckBox()

De esta forma si tienes 20 CheckBox, iras desde 0 hasta 19 instanciando los CheckBoxes en cada índice.

Saludos!


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 19 Noviembre 2012, 22:54 pm
Nada, gracias Hdm y Kubox, puse exactamente lo que me dijeron pero no me quiere funcionar esto:


Código
  1. Public Class Form1
  2.    Dim filesystem As Object, ThisDir As Object
  3.    Dim mCheck(0) As CheckBox 'matriz que contendrá los "X" CheckBox
  4. ...


Código
  1.    ' Form load
  2.    Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  3.        foldertextbox.Text = My.Settings.folderpath
  4.        updatecheckboxes()
  5.    End Sub



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

Código
  1.    ' update checkboxes
  2.    Public Sub updatecheckboxes()
  3.        Dim filesystem = CreateObject("Scripting.FileSystemObject")
  4.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  5.        Dim i As Int32 = 0
  6.        For Each folder In ThisDir.Subfolders
  7.            i = i + 1
  8.            Array.Resize(mCheck, i)
  9.            mCheck(i - 1) = New CheckBox()
  10.            MessageBox.Show("test")
  11.            Me.Panel1.Controls.Add(mCheck(i))
  12.            With mCheck(i)
  13.                .Name = "Checkbox" & i
  14.                .Text = folder.Name
  15.                .Location = New Point(10, i * 20)
  16.            End With
  17.            AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox
  18.        Next
  19.        CargarPropiedad()
  20.    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
  1. Public Class Form1
  2. ' el número aumentado a 999, sino no me funciona el segundo intento xD
  3.    Dim mCheck(999) As CheckBox
  4. ...

Código
  1.    ' update checkboxes
  2.    Public Sub updatecheckboxes()
  3.        Dim filesystem = CreateObject("Scripting.FileSystemObject")
  4.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  5.        Dim i As Int32 = 0
  6.        For Each folder In ThisDir.Subfolders
  7.            i = i + 1
  8.            mCheck(i) = New CheckBox()
  9.            'Array.Resize(mCheck, i)
  10.            MessageBox.Show("test")
  11.            Me.Panel1.Controls.Add(mCheck(i))
  12.            With mCheck(i)
  13.                .Name = "Checkbox" & i
  14.                .Text = folder.Name
  15.                .Location = New Point(10, i * 20)
  16.            End With
  17.            AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox 'Asocio el evento CheckedChange del CheckBox actual a la función LlamadaCheckBox
  18.        Next
  19.        CargarPropiedad() 'Cargo las propiedades una vez dibujados los CheckBoxes
  20.    End Sub


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: HdM en 19 Noviembre 2012, 23:02 pm
Hola.

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

Ej:

Código
  1. Me.Panel1.Controls.Add(mCheck(i))
  2. With mCheck(i)
  3.                .Name = "Checkbox" & i
  4.                .Text = folder.Name
  5.                .Location = New Point(10, i * 20)
  6. End With
  7. AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox
  8.  


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 19 Noviembre 2012, 23:09 pm
Nótese que actualizo la variable i y ReSizeo el Array al final del for, para que no tengas que cambiar nada.

Código
  1.  
  2. ' update checkboxes
  3.    Public Sub updatecheckboxes()
  4.        Dim filesystem = CreateObject("Scripting.FileSystemObject")
  5.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  6.        Dim i As Int32 = 0
  7.        For Each folder In ThisDir.Subfolders
  8.            mCheck(i) = New CheckBox()
  9.            MessageBox.Show("test")
  10.            Me.Panel1.Controls.Add(mCheck(i))
  11.            With mCheck(i)
  12.                .Name = "Checkbox" & i
  13.                .Text = folder.Name
  14.                .Location = New Point(10, i * 20)
  15.            End With
  16.            AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox
  17.            i = i + 1
  18.            Array.Resize(mCheck, i)
  19.        Next
  20.        CargarPropiedad()
  21.    End Sub
  22.  


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 19 Noviembre 2012, 23:14 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:

(http://img818.imageshack.us/img818/9628/prtscrcapture3k.jpg)


Vuelvo a abrir la app, y me aparece esto:

(http://img138.imageshack.us/img138/6184/prtscrcapture4p.jpg)


¿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
  1. Imports System.Windows.Forms
  2. Imports System.IO
  3.  
  4. Public Class Form1
  5.    Dim filesystem As Object, ThisDir As Object
  6.    Dim mCheck(0) As CheckBox 'matriz que contendrá los "X" CheckBox
  7.  
  8.    ' Start of Propertys
  9.    Public Property userSelectedPlayerFilePath() As String
  10.        Get
  11.            Return playertextbox.Text
  12.        End Get
  13.        Set(value As String)
  14.            playertextbox.Text = value
  15.        End Set
  16.    End Property
  17.  
  18.    Public Property userSelectedFolderPath() As String
  19.        Get
  20.            Return foldertextbox.Text
  21.        End Get
  22.        Set(value As String)
  23.            foldertextbox.Text = value
  24.        End Set
  25.    End Property
  26.  
  27.    Public Sub GenerarPropiedades() 'metodo que generará la propiedad al producirse el cierre del formulario
  28.        Dim CheckedN As String = Nothing 'la cadena que contendrá los CheckBoxes que estén Checkados
  29.        For i As Int32 = 0 To mCheck.Length - 1 'recorro la matriz de los CheckBoxes
  30.            If mCheck(i).Checked = True Then 'Si el CheckBox actual está checkado
  31.                CheckedN &= i + 1 'Obtengo su indice y lo meto al string (si es Checkbox1 pues 1, si es chckbx2 pues 2) ...
  32.            End If
  33.        Next
  34.        My.Settings.CuantosChecked = CheckedN 'Actualizo la propiedad
  35.        My.Settings.Save() 'Guardo la propiedad
  36.    End Sub
  37.  
  38.  
  39.    Public Sub CargarPropiedad() 'método que comprobará que CheckBoxes fueron tildados la útlima vez
  40.        Dim mCuantosChecked As Char() = My.Settings.CuantosChecked.ToCharArray 'Paso el String de la propiedad a una matriz
  41.        'Simplemente hago esto para separar el String por indices (un caracter por indice)
  42.        For Each caracter As Char In mCuantosChecked 'Recorro la matriz caracteres que contendrá los checboxes tildados
  43.            For Each CheckboxN In mCheck 'Recorro la matriz de CheckBoxes, para comparar si está o no está tildado
  44.                If CheckboxN.Name.Contains(caracter) Then
  45.                    'Si el CheckBox actual contiene cualquier caracter de la propiedad
  46.                    'que tiene los indices de los CheckBoxes tildados
  47.                    CheckboxN.Checked = True 'Lo tildo
  48.                End If
  49.            Next
  50.        Next
  51.    End Sub
  52.  
  53.  
  54.    ' update checkboxes
  55.    Public Sub updatecheckboxes()
  56.        ' delete the old checkboxes
  57.        Panel1.Controls.Clear()
  58.        ' create the new checkboxes
  59.        Dim filesystem = CreateObject("Scripting.FileSystemObject")
  60.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  61.        Dim i As Int32 = 1
  62.        'Dim mCheck() As CheckBox
  63.        For Each folder In ThisDir.Subfolders
  64.  
  65.            'mCheck(i - 1) = New CheckBox()
  66.            Array.Resize(mCheck, i)
  67.            mCheck(i - 1) = New CheckBox()
  68.            'MessageBox.Show("test")
  69.            Me.Panel1.Controls.Add(mCheck(i - 1))
  70.            With mCheck(i - 1)
  71.                .Name = "Checkbox" & i - 1
  72.                .Text = "Checkbox" & i - 1
  73.                ' .Text = folder.Name
  74.                .Location = New Point(10, i * 20)
  75.            End With
  76.            AddHandler mCheck(i - 1).CheckedChanged, AddressOf LlamadaCheckBox
  77.            i = i + 1
  78.        Next
  79.        CargarPropiedad()
  80.    End Sub
  81.  
  82.    ' Form close
  83.    Public Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
  84.        GenerarPropiedades()
  85.        'My.Settings.Save()
  86.    End Sub
  87.  
  88.  
  89.    ' Form load
  90.    Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  91.        playertextbox.Text = My.Settings.playerpath
  92.        foldertextbox.Text = My.Settings.folderpath
  93.        updatecheckboxes()
  94.    End Sub
  95.  
  96.  
  97.    ' Folder button
  98.    Public Sub C1Button3_Click(sender As Object, e As EventArgs) Handles folderbutton.Click
  99.        Dim folderselected As New System.Windows.Forms.FolderBrowserDialog
  100.        Dim Resultado As DialogResult
  101.        folderselected.RootFolder = Environment.SpecialFolder.Desktop
  102.        Resultado = folderselected.ShowDialog
  103.        If Resultado.ToString() = "OK" Then
  104.            userSelectedFolderPath = folderselected.SelectedPath
  105.            My.Settings.folderpath = folderselected.SelectedPath
  106.            My.Settings.Save()
  107.            updatecheckboxes()
  108.        End If
  109.    End Sub
  110.  
  111.  
  112.    ' Player button
  113.    Public Sub C1Button1_Click(sender As Object, e As EventArgs) Handles playerbutton.Click
  114.        Dim playerselected As New OpenFileDialog()
  115.        playerselected.InitialDirectory = Environ("programfiles")
  116.        playerselected.Title = "Select your favorite music player"
  117.        playerselected.Filter = "Music players|mpc.exe;mpc-hc.exe;mpc-hc64.exe;umplayer.exe;vlc.exe;winamp.exe;wmp.exe"
  118.        PlayerDialog.FilterIndex = 1
  119.        Dim selection As System.Windows.Forms.DialogResult = playerselected.ShowDialog()
  120.        If selection = DialogResult.OK Then
  121.            userSelectedPlayerFilePath = playerselected.FileName
  122.            My.Settings.playerpath = playerselected.FileName
  123.            My.Settings.Save()
  124.        End If
  125.    End Sub
  126.  
  127.  
  128.    ' Play button
  129.    Public Sub C1Button2_Click(sender As Object, e As EventArgs) Handles C1Button2.Click
  130.        'Process.Start(userSelectedPlayerFilePath, ControlChars.Quote & Path.Combine(ThisDir.Path, checkedpath1) & ControlChars.Quote)
  131.    End Sub
  132.  
  133.  
  134.  
  135.    ' función que se ejecuta cuando cualquier checkbox es clickado
  136.    Public Sub LlamadaCheckBox(ByVal sender As Object, ByVal e As System.EventArgs)
  137.        Dim CheckboxN As CheckBox = CType(sender, CheckBox) 'a partir del sender creo el CheckBox (paso de objet a CheckBox para poder utilizar sus propiedades)
  138.        'MsgBox(CheckboxN.Name)
  139.  
  140.    End Sub
  141.  
  142. End Class


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 19 Noviembre 2012, 23:21 pm
Código
  1. ' update checkboxes
  2.    Public Sub updatecheckboxes()
  3.        Dim filesystem = CreateObject("Scripting.FileSystemObject")
  4.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  5.        Dim i As Int32 = 0
  6.        For Each folder In ThisDir.Subfolders
  7.            mCheck(i) = New CheckBox()
  8.            MessageBox.Show("test")
  9.            Me.Panel1.Controls.Add(mCheck(i))
  10.            With mCheck(i)
  11.                .Name = "Checkbox" & i +1 'De esta forma sumas 1 y tendrás CheckBox1,2,3
  12.                .Text = "CheckBox" & i+1 'Lo mismo para el nombre
  13.                .Location = New Point(10, i * 20)
  14.            End With
  15.            AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox
  16.            i = i + 1
  17.            Array.Resize(mCheck, i)
  18.        Next
  19.        CargarPropiedad()
  20.    End Sub


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 19 Noviembre 2012, 23:24 pm
No Kubox, he usado ahora mismo tu ejemplo y solo se muestra UN checkbox:

(http://img546.imageshack.us/img546/2697/prtscrcapture5.jpg)

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


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 19 Noviembre 2012, 23:29 pm
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


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: HdM en 19 Noviembre 2012, 23:36 pm
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
  1. For Each CheckboxN In mCheck 'Recorro la matriz de CheckBoxes, para comparar si está o no está tildado
  2.                If CheckboxN.Name.Contains(caracter) Then
  3.                    'Si el CheckBox actual contiene cualquier caracter de la propiedad
  4.                    'que tiene los indices de los CheckBoxes tildados
  5.                    CheckboxN.Checked = True 'Lo tildo
  6.                End If
  7. Next
  8.  

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.


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 19 Noviembre 2012, 23:41 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"?

Código:
f CheckboxN.Name.Contains(caracter) Then

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


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Keyen Night en 20 Noviembre 2012, 00:37 am
que buscarias capturar con la expresion regular?


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 20 Noviembre 2012, 00:41 am
que buscarias capturar con la expresion regular?

Hola, pues la interpretación que le haría en Ruby sería esta:
Código
  1. If CheckboxN.Name[(/^#{Regexp.escape(caracter)}$/)] Then...

Busca el "caracter" como una palabra con inicio y final de línea, de esa manera si el checkbox se llama "1", con ese regex excluiría todos los demás checkboxes: "10","11","12",etc.. ¿No?

Me iría muy bien, pero lo he intentado y me da error:
Código
  1. Dim reg As New Regex(caracter)
  2. If reg.Match(CheckboxN.Name) Then

Value of type 'System.Text.RegularExpressions.Match' cannot be converted to 'Boolean'.

EDITO
: Pensandolo bien, tengo que usar el string "checkbox" + (caracter) en el regex xD

un saludo


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 20 Noviembre 2012, 00:48 am
Gracias HdM por sacar el error, pues éste es vital para el posterior funcionamiento. Para cambiar el tipo de propiedad en My.Settings hay que hacerlo de forma manual, especificando en la propiedad en el archivo Designer.Vb el tipo Integer() o Int32().

He modificado el código para que no Checkee CheckBoxes que no fueron seleccionados, ahora se trabaja con una propiedad llamada "Valores" que guarda una lista de enteros que representa los índices de los CheckBoxes que fueron tildados al cerrar el programa. Al iniciar la aplicación se dibujan los CheckBoxes y se procede a comprobar la propiedad. El código está mal estructurado, pero EleKtro, es para que puedas ver lo que hago de forma simple. Recuerda que hay que ser limpios xD

Código
  1. Public Class Form1
  2.    Dim mcheck(0) As CheckBox
  3.    Private Sub CargarPropiedades()
  4.        'Obtenemos la Lista de Enteros de los índices Checkados
  5.        Dim ListaCheckados As Int32() = My.Settings.Valores
  6.        For i As Int32 = 0 To mcheck.Length - 1 'Recorro los CheckBoxes
  7.            For Each indiceCheckado As Int32 In ListaCheckados 'Por cada indice de CheckBoxes checkados
  8.                'Como se los indices de los CheckBoxes checkados, accedo a éstos mediante el Array de los CheckBoxes
  9.                'Ej -> indiceCheckado : 3 (CheckBox3) ;
  10.                'Por lo tanto indiceCheckado - 1 = 2, mCheck(0) = check1, ... m(2) = CheckBox3
  11.                'Es decir el índice N - 1 siempre corresponderá a CheckBoxN
  12.                mcheck(indiceCheckado - 1).Checked = True
  13.            Next
  14.        Next
  15.    End Sub
  16.  
  17.    Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
  18.        Dim mCheckados(0) As Int32 'matriz que guardará los indices de los CheckBoxes checkados
  19.        Dim Cuantos As Int32 = 0 'cuantos CheckBoxes estan checkados
  20.        For i As Int32 = 0 To mcheck.Length - 1 'Recorro los CheckBoxes en busca de Checkados
  21.            If mcheck(i).Checked = True Then
  22.                Cuantos += 1
  23.                'Sumamos un indice por CheckBox checkado
  24.                Array.Resize(mCheckados, Cuantos)
  25.                mCheckados(Cuantos - 1) = i + 1 'metemos en el indice del Array el elemento Checkado (RECUERDA SE EMPIEZA DESDE 0)
  26.                'Por eso lo de Cuantos - 1 (Si tienes 7 Checkados ira desde 0 hasta 6 ...)
  27.            End If
  28.        Next
  29.        My.Settings.Valores = mCheckados 'Actualizamos la propiedades Int32()
  30.        My.Settings.Save()
  31.    End Sub
  32.    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  33.  
  34.        For i As Int32 = 0 To 20
  35.            Array.Resize(mcheck, i + 1)
  36.            mcheck(i) = New CheckBox
  37.            With mcheck(i)
  38.                .Name = "CheckBox" & i + 1
  39.                .Text = mcheck(i).Name
  40.                .Location = New Point(40, i * 40)
  41.            End With
  42.            Me.Controls.Add(mcheck(i))
  43.        Next
  44.        CargarPropiedades()
  45.    End Sub
  46. End Class
  47.  

Espero que te haya servido de ayuda,

Saludos!


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 20 Noviembre 2012, 06:30 am
He probado el form pero no me funciona:

Código
  1. Dim ListaCheckados As Int32() = My.Settings.Valores
Citar
Error 7       Value of type 'Integer' cannot be converted to '1-dimensional array of Integer'.   

Código
  1. My.Settings.Valores = mCheckados
Citar
Error   8   Value of type '1-dimensional array of Integer' cannot be converted to 'Integer'.   


Para cambiar el tipo de propiedad en My.Settings hay que hacerlo de forma manual, especificando en la propiedad en el archivo Designer.Vb el tipo Integer() o Int32().
(http://img17.imageshack.us/img17/262/prtscrcapture3px.jpg)

¿Eso es hacerlo de forma manual, o estoy omitiendo algo?
Vale creo que te referías aquí:

Código
  1.        <Global.System.Configuration.UserScopedSettingAttribute(), _
  2.         Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
  3.         Global.System.Configuration.DefaultSettingValueAttribute("0")> _
  4.        Public Property Valores() As Int32()
  5.            Get
  6.                Return CType(Me("Valores"), Int32())
  7.            End Get
  8.            Set(value As Int32())
  9.                Me("Valores") = value
  10.            End Set
  11.        End Property
  12.    End Class
  13. End Namespace

Es que yo no tengo un "form1.designer.vb" y acabo de conocer su existencia googleando...

Estoy acoplando tu form a mi form, a ver si por fin conseguimos que funcione...

(Infinitas) Gracias Kubox

EDITO: SÍ!!!

Me ha costado un poco adaptarlo a mi form pero al final lo he conseguido, y todo lo relativo al tema funciona bien

PD: Será una mier** mi programa pero sin duda kubox, Hdm, y Danyfirex os llevais unos agardecimientos en algún botón de la app xD

Ya puedo decir eso de... TEMA SOLUCIONADO!!!! ...O casi, porque aún me queda una duda esporádica...

¿Como puedo resetear el índice/tabla de la matriz?

Es decir, dejarlo todo "en blanco"... para poder borrar/añadir checkboxes una y otra vez sin que se salga fuera dle índice...

Mi app usa "folderbrowserdialog" para almacenar una ruta en "my.settings",
Cuando se abre el programa, esa ruta se carga en el evento form_load, Kubox, tu magnifico code se encarga de indizarlo y crear los checkboxes y tál una vez cargada la ruta, añadiendole el nombre de la carpeta a la propiedad "text" de cada checkbox.

El problema sucede cuando intento cargar una segunda ruta (osea, cuando uso el botón del folderbrowserdialog dentro de la app y selecciono una carpeta para que séa "cargada"), obtengo este error:

Código:
Index was outside the bounds of the array.
En:
Código
  1.    Private Sub CargarPropiedades()
  2.                mcheck(indiceCheckado - 1).Checked = True
  3.    End Sub


Y este es mi noob intento de reseteo antes de llamar al sub que llama al sub de "cargarpropiedades":

Código
  1.    ' Folder button
  2.    Public Sub C1Button3_Click(sender As Object, e As EventArgs) Handles folderbutton.Click
  3.     ...
  4.        If Resultado.ToString() = "OK" Then
  5.            Dim mcheck(0) As CheckBox
  6.            updatecheckboxes()

y este es el sub que falta, por si acaso estuviera mal lo posteo:
Código
  1.    ' update checkboxes
  2.    Public Sub updatecheckboxes()
  3.        ' delete the old checkboxes
  4.        Panel1.Controls.Clear()
  5.        ' create the new checkboxes
  6.        Dim filesystem = CreateObject("Scripting.FileSystemObject")
  7.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  8.        Dim i As Int32 = 0
  9.        For Each folder In ThisDir.Subfolders
  10.            'MessageBox.Show("a")
  11.            Array.Resize(mcheck, i + 1)
  12.            mcheck(i) = New CheckBox
  13.            With mcheck(i)
  14.                .Name = "CheckBox" & i + 1
  15.                '.Text = mcheck(i).Name
  16.                .Text = folder.Name
  17.                .Location = New Point(10, i * 20)
  18.            End With
  19.            Me.Panel1.Controls.Add(mcheck(i))
  20.            AddHandler mcheck(i).CheckedChanged, AddressOf LlamadaCheckBox
  21.            i += 1
  22.        Next
  23.        CargarPropiedades()
  24.    End Sub


GRACIAS POR VUESTRA PACIENCIA


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 20 Noviembre 2012, 09:59 am
Cuando dibujas nuevos controles la cantidad de CheckBoxes no tiene porque ser la misma que la anterior. Si tenias 20 CheckBoxes ya que encontraste 20 subdirectorios, y luego llamas al FolderBrowserDialog() quizás tengas una mayor cantidad de Controles y por eso es por lo que obtienes un error en conjunto con la propiedad. Me explico, si antes tenias 20 CheckBoxes en la matriz y ahora encontraste 10 subdirectorios pues en la matriz tendrás 30 ya que tienes que resetearla. Otro error es que antes tuvieras el Checkbox10 activado y ahora solo tengas dibujados 7 CheckBoxes e intentes Checkar ese 10. (Ahí te salta error en lo que dijiste de la proiedad).

Para resetear la matriz llama a este método :P

No he probado el código, ni tampoco le he dado muchas vueltas (estoy en clase :P) pero te adjunto algo:
Código
  1.    Dim mCheck(0) As CheckBox
  2.  
  3.    Private Sub UpdateArray()
  4.        Array.Clear(mCheck, 0, mCheck.Length)
  5.        Array.Resize(mCheck, 0)
  6.    End Sub
  7.  

Saludos!


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 20 Noviembre 2012, 10:08 am
Pues no, no me funciona el sub :-/

Tanto con tu sub como con "ReDim", y con "Array.Clear" obtengo el mismo error en el mismo sitió que comenté antes "el indice está fuera de blablabla...", algo estoy omitiendo o haciendo mal

Sobre lo que comentas de un checkbox10 y cargar menor cantidad de 10 checkboxes, pues también debo resetear eso entonces al cargar una carpeta :-/

Un saludo

EDITO:
Kubox, lo he arreglado por arte de mágia, realmente no se lo que ha pasado, empecé a probar cosas, y al volver pasos atrás en la IDE ("ctrl+z") ahora me funciona, SIN REDIMENSIONAR EL ARRAY NI NADA, ya te digo, por arte de mágia, no veo ni una pequeña modificación en la class...

Ahora puedo cargar las rutas que quiera y no me da error :S, tampoco me da error si cargo una ruta con 20 carpetas, selecciono el checkbox 20, y cargo una carpeta de 2 subfolders... (se selecciona el checkbox 2 xD)

Pues nada, un sufrimiento menos, ahora lo que necesitaría es resetear los checkboxes que se quedan clickados al cargar distintas rutas...


Retiro lo dicho, guardé el proyecto tal y como estaba, ahora he vuelto a abrir la ide, he ejecutado la app y me vuelve a dar el mismo problema del "index out of range", ha debido ser algún bug extraño del VS...porque no entiendo que me funcionase haciendo "pasos atrás" y ahora de nuevo no me vuelve a funcionar al cargar una ruta, muy raro.


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 20 Noviembre 2012, 12:13 pm
Tengo el form casi terminado, lo único que me falta es eso, arreglar lo de los "reseteos" para que no me de error al usar el botón para cargar una ruta...

aquí adjunto el form completo por si sirve de algo:

Código
  1. Imports System.Windows.Forms
  2. Imports System.IO
  3. Imports System.Text.RegularExpressions
  4.  
  5. Public Class Form1
  6.    Dim filesystem As Object, ThisDir As Object
  7.    Dim mcheck(0) As CheckBox
  8.    Dim winampargs As String

Código
  1. #Region "Propertys"
  2.    Public Property userSelectedPlayerFilePath() As String
  3.        Get
  4.            Return playertextbox.Text
  5.        End Get
  6.        Set(value As String)
  7.            playertextbox.Text = value
  8.        End Set
  9.    End Property
  10.  
  11.    Public Property userSelectedFolderPath() As String
  12.        Get
  13.            Return foldertextbox.Text
  14.        End Get
  15.        Set(value As String)
  16.            foldertextbox.Text = value
  17.        End Set
  18.    End Property
  19. #End Region

Código
  1. #Region "Load / Close"
  2.  
  3.    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  4.        playertextbox.Text = My.Settings.playerpath
  5.        foldertextbox.Text = My.Settings.folderpath
  6.        updatecheckboxes()
  7.    End Sub
  8.  
  9.    Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
  10.        Dim mCheckados(0) As Int32
  11.        Dim Cuantos As Int32 = 0
  12.        For i As Int32 = 0 To mcheck.Length - 1
  13.            If mcheck(i).Checked = True Then
  14.                Cuantos += 1
  15.                Array.Resize(mCheckados, Cuantos)
  16.                mCheckados(Cuantos - 1) = i + 1
  17.            End If
  18.        Next
  19.        My.Settings.Valores = mCheckados
  20.        My.Settings.Save()
  21.    End Sub
  22.  
  23. #End Region

Código
  1. #Region "Save & Get settings"
  2.  
  3.    Public Sub GenerarPropiedades()
  4.        Dim CheckedN As String = Nothing
  5.        For i As Int32 = 0 To mcheck.Length - 1
  6.            If mcheck(i).Checked = True Then
  7.                CheckedN &= i + 1
  8.            End If
  9.        Next
  10.        My.Settings.Save()
  11.    End Sub
  12.  
  13.    Private Sub CargarPropiedades()
  14.        'Obtenemos la Lista de Enteros de los índices Checkados
  15.        Dim ListaCheckados As Int32() = My.Settings.Valores
  16.        For i As Int32 = 0 To mcheck.Length - 1
  17.            For Each indiceCheckado As Int32 In ListaCheckados
  18.                mcheck(indiceCheckado - 1).Checked = True
  19.            Next
  20.        Next
  21.    End Sub
  22.  
  23. #End Region

Código
  1. #Region "Draw checkboxes..."
  2.  
  3.    Public Sub updatecheckboxes()
  4.        ' delete the old checkboxes
  5.        Panel1.Controls.Clear()
  6.        ' create the new checkboxes
  7.        Dim filesystem = CreateObject("Scripting.FileSystemObject")
  8.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  9.        Dim i As Int32 = 0
  10.        For Each folder In ThisDir.Subfolders
  11.            Array.Resize(mcheck, i + 1)
  12.            mcheck(i) = New CheckBox
  13.            With mcheck(i)
  14.                .AutoSize = True
  15.                .Location = New Point(10, i * 20)
  16.                .Name = "CheckBox" & i + 1
  17.                .Text = folder.Name
  18.            End With
  19.            Me.Panel1.Controls.Add(mcheck(i))
  20.            AddHandler mcheck(i).CheckedChanged, AddressOf LlamadaCheckBox
  21.            i += 1
  22.        Next
  23.        CargarPropiedades()
  24.    End Sub
  25.  
  26.    ' función que se ejecuta cuando cualquier checkbox es clickado
  27.    Public Sub LlamadaCheckBox(ByVal sender As Object, ByVal e As System.EventArgs)
  28.        Dim filesystem = CreateObject("Scripting.FileSystemObject")
  29.        Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath)
  30.        Dim CheckboxN As CheckBox = CType(sender, CheckBox)
  31.        If CheckboxN.Checked = True Then
  32.            winampargs = winampargs & " " & ControlChars.Quote & Path.Combine(ThisDir.Path, CheckboxN.Text.ToString()) & ControlChars.Quote
  33.        Else
  34.            winampargs = Replace(winampargs, ControlChars.Quote & Path.Combine(ThisDir.Path, CheckboxN.Text.ToString()) & ControlChars.Quote, "")
  35.        End If
  36.    End Sub
  37.  
  38. #End Region

Código
  1. #Region "buttons"
  2.  
  3.    ' Folder button
  4.    Public Sub C1Button3_Click(sender As Object, e As EventArgs) Handles folderbutton.Click
  5.        Dim folderselected As New System.Windows.Forms.FolderBrowserDialog
  6.        Dim Resultado As DialogResult
  7.        folderselected.RootFolder = Environment.SpecialFolder.Desktop
  8.        Resultado = folderselected.ShowDialog
  9.        If Resultado.ToString() = "OK" Then
  10.            userSelectedFolderPath = folderselected.SelectedPath
  11.            My.Settings.folderpath = folderselected.SelectedPath
  12.            My.Settings.Save()
  13.            Dim mcheck(0) As CheckBox
  14.            updatecheckboxes()
  15.        End If
  16.    End Sub
  17.  
  18.    ' Player button
  19.    Public Sub C1Button1_Click(sender As Object, e As EventArgs) Handles playerbutton.Click
  20.        Dim playerselected As New OpenFileDialog()
  21.        playerselected.InitialDirectory = Environ("programfiles")
  22.        playerselected.Title = "Select your favorite music player"
  23.        playerselected.Filter = "Music players|mpc.exe;mpc-hc.exe;mpc-hc64.exe;umplayer.exe;vlc.exe;winamp.exe;wmp.exe"
  24.        PlayerDialog.FilterIndex = 1
  25.        Dim selection As System.Windows.Forms.DialogResult = playerselected.ShowDialog()
  26.        If selection = DialogResult.OK Then
  27.            userSelectedPlayerFilePath = playerselected.FileName
  28.            My.Settings.playerpath = playerselected.FileName
  29.            My.Settings.Save()
  30.        End If
  31.    End Sub
  32.  
  33.    ' Play button
  34.    Public Sub C1Button2_Click(sender As Object, e As EventArgs) Handles C1Button2.Click
  35.        Process.Start(userSelectedPlayerFilePath, winampargs)
  36.    End Sub
  37.  
  38. #End Region

Código
  1. End Class


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 20 Noviembre 2012, 12:50 pm
Buenas EleKtro!

Te diría que debugeases la applicación o bien poniendo Breakpoints en los puntos que te interesa evaluar o bien llendo paso a paso por sentencia. Si cargas la app y el directorio es C:\ se dibujaran tantos CheckBoxes como directorios en C:\. Luego imaginate que cargas C:\musica, entonces se añadiran tantos CheckBox como directorios en C:\musica haya, pero claro, estas guardando en la propiedad FolderPathName el ultimo directorio cargado. Si inicias la app otra vez la propiedad que guarda el indice de los CheckBoxes checkados tendra un tamaño mayor a la que se espera pues solo estas dibujando tantos Checkbox como directorios en C:\musica, pero resulta que tambien cargas los de C:\ pues antes al cerrar la aplicación se guardaron los de C:\ y C:\musica.

No sé si ése será el error, el código parece estar bien. Ojala mis ojos fueran un debugger pero a tanto no llego xD como ultimo recurso pasame la solucion del proyecto y te busco el error.

Saludos!


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 20 Noviembre 2012, 13:10 pm
Quizás este comentario resulta un poco OFFTOPIC, pero es para decirte que en estas últimas horas ya lo he intentado todo (todo lo que está bajo mis conocimientos en VB, que son pocos xD) y no he conseguido arreglar eso, así que como no me lo arregle un pro como tú... :xD

Dentro de 1-2 horas me pongo de nuevo al tema a ver si puedo solucionarlo yo solo con los datos que me acabas de dar, es que me da palo pedirte cosas ya, y sinó lo consigo en un rato pues te paso la "solución" por mp más tarde vale?

hasta un rato :)        (Y GRAAAAAAAACIAS, mi salvador! :xD)


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: HdM en 20 Noviembre 2012, 13:11 pm
Hola.

Yo el error veo que está en que cada vez que seleccionas un directorio, llamas al updatecheckboxes(), redibujando los checkbox y éste a su vez llama al CargarPropiedades(), que tiene almacenados los checkbox que había creados en la apertura del form. Es posible que el nº de checkbox actualmente dibujados, no coincida con los índices de checkbox almacenados en My.Settings.Valores y eso produce el error.

Ten en cuenta que en CargarPropiedades(), por cada checkbox dibujado, estás recorriendo todos los índices de los checkbox almacenados en My.Settings.Valores.

Saludos.


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Novlucker en 20 Noviembre 2012, 14:12 pm
Necesito un resumen :xD

En tu app;
  • Seleccionas un directorio
  • Listas todos los subdirectorios
  • Creas un checkbox por cada subdirectorio
  • ¿Para que son las settings?

Saludos


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Keyen Night en 20 Noviembre 2012, 14:13 pm
Necesito un resumen :xD

En tu app;
  • Seleccionas un directorio
  • Listas todos los subdirectorios
  • Creas un checkbox por cada subdirectorio
  • ¿Para que son las settings?

Saludos

x2 Yo también iba a publicar lo mismo :-X :xD El problema se ha desbordado un poco no?


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 20 Noviembre 2012, 14:27 pm
Encontré el error, es lo que te dije antes y no es por el código si no por las rutas cargadas. Esta vez te lo intentaré explicar lo mejor posible :P

cuando se inicia la App se dibujan los CheckBoxes de la ruta actual. Si cargas mas rutas a través del FolderButton() entonces se añaden mas CheckBoxes (la matriz mCheck tendrá mas índices). Hasta ahí bien. Aunque llames a CargarPropiedades() todo seguirá bien ya que tendrás los mismos índices que cuando cargaste la primera ruta.

El problema se presenta al cerrar la aplicación, pues imagínate que la ruta que cargaste al principio del programa genera 10 Checkboxes y la que cargaste con FolderButton genera 5 CheckBoxes más. Si antes de cerrar el programa tildaste el CheckBox 12,13 y 14 cuando abras la App otra vez sólo se dibujarán los CheckBoxes de la última ruta cargada (los 5 que generaste mediante FolderButton). Entonces la matriz mCheck tendrá 5 índices y le será imposible acceder al índice 12,13 y 14 pues esos índices los generaste cuando tenías 15 CheckBoxes Y AHORA TIENES 5 no los 15 que generaste por última vez (cargas el último directorio asignado a la propiedad, no los anteriores :/)

Tienes que idear un método para que se carguen las últimas rutas cargadas en el formulario, de esta forma podrás dibujar todos los CheckBoxes de ambas rutas y posteiormente comprobar si fueron tildados la última vez. Puedes hacerlo con una propiedad que guarde una matriz de cadenas String().

Espero que lo entiendas, pues el error es bastante crítico xD Si no lo entendieras pues podría ayudarte mediante código, pero estaría bien que pudieras arreglarlo pues es la mejor manera de comprender el funcionamiento del programa. Cualquier duda aquí me tienes.

Saludos!


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 20 Noviembre 2012, 15:02 pm
  • Seleccionas un directorio
  • Listas todos los subdirectorios
  • Creas un checkbox por cada subdirectorio
  • ¿Para que son las settings?

Hola Novlucker,

Me sirvo de la setting/propiedad para almacenar la referencia de los checkboxes que están seleccionados antes de cerrar la app, al volver a abrir la app se recorre la propiedad buscando los checkboxes de "la última sesión" para que se seleccionen automáticamente.



x2 Yo también iba a publicar lo mismo :-X :xD El problema se ha desbordado un poco no?
La verdad es que sí, me parece increible que este tipo de MINI-aplicación tán insignificante requiera tanto esfuerzo.



El problema se presenta al cerrar la aplicación, pues imagínate que la ruta que cargaste al principio del programa genera 10 Checkboxes y la que cargaste con FolderButton genera 5 CheckBoxes más. Si antes de cerrar el programa tildaste el CheckBox 12,13 y 14 cuando abras la App otra vez sólo se dibujarán los CheckBoxes de la última ruta cargada (los 5 que generaste mediante FolderButton). Entonces la matriz mCheck tendrá 5 índices y le será imposible acceder al índice 12,13 y 14

por esa regla de trés, una posibilidad sería, como los checkboxes tildados se guardan en la propiedad "valores", pues vaciar la propiedad antes de cargar la nueva ruta... ¿Me equivoco o voy bien?

Tienes que idear un método para que se carguen las últimas rutas cargadas en el formulario, de esta forma podrás dibujar todos los CheckBoxes de ambas rutas y posteiormente comprobar si fueron tildados la última vez. Puedes hacerlo con una propiedad que guarde una matriz de cadenas String().
Si lo que he comentado en la cita anterior es así entonces puedo omitir el tener que idear ese método... ¿no?
Kubox, entenderlo lo entiendo (o eso creo), otra cosa es que tenga idea de como idear ese método para solventarlo, y sí... es un error muy crítico, y jod*er, si consigo arreglar eso ya tengo la aplicación hecha.

Vamos que en resumen, el error reside en que en "valores" se guardan los indices de la última ruta cargada, y claro al cargar una ruta nueva (Si tiene menos checkboxes o más que el indice) se jode todo... ¿no?

Pues como no tengo ni idea de idear nada semejante para arreglarlo, esto me parece más sencillo (pero no se si es posible hacerlo), a ver que opinas:

1. Se ejecuta la app (el primer uso de la app), aki no hay ninguna carpeta cargada porque se tiene que usar el botón del FolderBrowserDialog para cargarla.
2. Le damos al botón y cargo una ruta, se indexa y se guarda.
3. pincho en algunos checkboxes.
3. Ahora me apetece cargar otra ruta, pues sigo el mismo procedimiento del paso 2, pero esta vez, justo antes de cargar la nueva ruta, vacío la propiedad "valores", osea, lo dejo como estaba al princpio, con un valor de "0", elimino todas las "entradas" que hubiera en la propiedad "Valores", así ya no hay problemas con el índice ni con nada y los checkboxes se crearían y se indexarían correctamente como en el primer uso del programa, y al cerrarse se cerraría correctamente porque "valores" solo contendría los valores de esta ultima ruta cargada...


Solo es un planteamiento... ¿Está bien?, ¿Es posible hacerlo?

Un saludo


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Novlucker en 20 Noviembre 2012, 15:17 pm
Lo he hecho rápidamente, el código es MUY mejorable :P

Código
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.IO;
  10. using System.Xml.Serialization;
  11.  
  12. namespace WindowsFormsApplication1
  13. {
  14.    public partial class Form1 : Form
  15.    {
  16.        public Form1()
  17.        {
  18.            InitializeComponent();
  19.        }
  20.  
  21.        private void Form1_Load(object sender, EventArgs e)
  22.        {
  23.            List<string> savedPath = GetSavedPaths();
  24.            DirectoryInfo folder = new DirectoryInfo(@"D:\Tools\");
  25.            DirectoryInfo[] subFolders = folder.GetDirectories();
  26.            int top = 10;
  27.            foreach (DirectoryInfo subFolder in subFolders)
  28.            {
  29.                CheckBox c = new CheckBox() { Left = 20, Top = top, AutoSize = true, Text = subFolder.FullName};
  30.                c.Checked = savedPath.Contains(subFolder.FullName);
  31.                c.CheckedChanged += new System.EventHandler(this.checkBox_CheckedChanged);
  32.                top += 20;
  33.                this.Controls.Add(c);
  34.            }
  35.        }
  36.  
  37.        private void SavePaths()
  38.        {
  39.            List<string> paths = new List<string>();
  40.  
  41.            foreach (Control c in Controls)
  42.                if (c is CheckBox && ((CheckBox)c).Checked)
  43.                        paths.Add(c.Text);
  44.  
  45.            using (StreamWriter sw = new StreamWriter("setting.xml"))
  46.            {
  47.                XmlSerializer serializer = new XmlSerializer(typeof(List<string>));
  48.                serializer.Serialize(sw, paths);
  49.                sw.Flush();
  50.            }
  51.        }
  52.  
  53.        private List<string> GetSavedPaths()
  54.        {
  55.            List<string> paths;
  56.  
  57.            try
  58.            {
  59.                using (StreamReader sr = new StreamReader("setting.xml"))
  60.                {
  61.                    XmlSerializer serializer = new XmlSerializer(typeof(List<string>));
  62.                    paths = (List<string>)serializer.Deserialize(sr);
  63.                }
  64.            }
  65.            catch
  66.            {
  67.                paths = new List<string>();
  68.            }
  69.  
  70.            return paths;
  71.        }
  72.  
  73.        private void checkBox_CheckedChanged(object sender, EventArgs e)
  74.        {
  75.            MessageBox.Show(((CheckBox)sender).Text);
  76.        }
  77.  
  78.        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  79.        {
  80.            SavePaths();
  81.        }
  82.    }
  83. }
  84.  

Saludos


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: HdM en 20 Noviembre 2012, 15:35 pm
@Novlucker: jajaja, estás en la champions.

@EleKtro: ¿Por qué no sacas el CargarPropiedades() fuera del updatecheckboxes()? Si no entiendo mal lo que quieres hacer, sólo se debe pasar por el CargarPropiedades() al iniciar la app., ¿no? De modo que ¿para qué pasar por ese sub cada vez se llama a updatecheckboxes()?

Saludos.


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: seba123neo en 20 Noviembre 2012, 16:00 pm
me lei todo y todavia no entendi :xD, en realidad entendi, pero no cual es el problema, es simplemente guardar el estado de los checkbox y la ultima ruta que seleccionaste. pero como tenes 2 rutas se te borran las anteriores, pues simplemente guardas para cada path determinado tanta cantidad de checkboxes y de esa forma cada ves que cambias de ruta tenes lo ultimo que seleccionaste.

por ejemplo la carpeta c:\prueba genera 2 checkbox, tildas los 2 por ejemplo:

 - check 1
 - check 2

despues vas y seleccionas la carpeta c:\prueba2 que genera 3 checkboxes mas (aca ya tenes que guardar los checkboxes anteriores, y guardar la ruta tambien).

 - check 1
 - check 2
 - check 3

supongamos que tildas los 3.

entonces si ahora vas y seleccionas otra ves la carpeta anterior c:\prueba debes cargar los primeros 2 check.

o sea el path es lo que importa aca, despues segun el path cargas los checkbox que se crearon.

pero antes tendrias que hacer una validacion tambien de si existe la carpeta, porque si yo voy y borro un subdirectorio y despues cargas los valores guardados ese directorio no existe mas, por lo tanto el checkbox tampoco deberia aparecer.



Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 20 Noviembre 2012, 16:06 pm
Lo he hecho rápidamente, el código es MUY mejorable :P
Gracias Nov!

Pero antes de convertilo a NET... perdona la ignoracía: ¿Que co** se supone que hace ese form?  :xD ¿Es una posible solución al problema que he expuesto? ¿O es un ejemplo de otra cosa?, es que yo solo veo un form en C# a simple vista xD, explícame un poco que es, ché!



@EleKtro: ¿Por qué no sacas el CargarPropiedades() fuera del updatecheckboxes()? Si no entiendo mal lo que quieres hacer, sólo se debe pasar por el CargarPropiedades() al iniciar la app., ¿no?

...
...
...
OMG

Pues sí !!, modificandolo de lugar parece que se han solucionado todos los problemas (parece) :xD

Tán fácil como eso... para tí ha sido muy obvio ver donde estaba el fallo pero yo llevo una mañana entera sin poder verlo jaja, en fin, muchas gracias Hdm,
aún tengo que testearlo un poco, que no me fío nada, me ha parecido demasiado fácil la modificación...

Pero creo que esta vez si...



@seba123neo

Lo mismo te digo, muchas gracias por la ayuda, pero creo que con la pequeña modificación que me dijo Hdm ya lo he dsolucionado y no me hará falta seguir los pasos que comentas.

Lo de la validacion del directorio es algo importante y buena idea, me me lo apunto en el "ToDoList" de la app :xD

Un saludo.


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: kub0x en 20 Noviembre 2012, 17:34 pm
Lo que hace NovLucker es guardar los subdirectorios de una ruta en un archivo xml serializado en funcion del Checkbox, pues si éste está checkado guarda la ruta . Posteriormente puedes acceder a dichos datos a través de GetSavedsPaths() e ir checkando los CheckBoxes.Sería algo como "tus rutas de música favoritas". Buen aporte sin duda :)

Estoy ciego, gracias HdM por aportar la solución pues no ví que se borraban los CheckBoxes dibujados al llamar a updatecheckboxes() y me lié pensando en otra cosa xD. Debería funcionar bien, ya que cargas la última ruta, obtienes los indices checkados y dibujas los Checkboxes (Todo en el evento Load) . Al quitar el método CargarPropiedades() de updatecheckboxes() te aseguras que si cargas una nueva ruta, se dibujen nuevos CheckBoxes y no haya conflictos si la cantidad es menor a la anterior.

Disfruta de la app :D


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Novlucker en 20 Noviembre 2012, 17:37 pm
Ese código;
  • Al cargar el form carga las rutas de los checkbox guardados
  • Lista los subdirectorios en D:\Tools (solo un ejemplo, ahora lo cambié a test)
  • Crea un form con checkbox y sus paths
  • Al dar click en un checkbox muestra el path correspondiente
  • Al cerrar el form vuelve a guardar las rutas

(http://i47.tinypic.com/kukgz.png)
carpeta1, carpeta2 son subdirectorios que cree para el ejemplo

Saludos


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: HdM en 20 Noviembre 2012, 18:31 pm
Ok, pues si te funca bien con el cambio, perfecto entonces. Cuando lo comercialices y te forres, acuérdate de los amigos  :silbar: XDDDD


Título: Re: [VS] ¿clonar evento para varios elementos? ¿FOR?
Publicado por: Eleкtro en 21 Noviembre 2012, 10:05 am
Ok, pues si te funca bien con el cambio, perfecto entonces. Cuando lo comercialices y te forres, acuérdate de los amigos  :silbar: XDDDD

si si que funciona con lo que me dijiste Hdm, y puedo dar el tema como solucionado ya.

Mi programa es una mi**** aunque lo he hecho en idioma inglés y pienso compartirlo, es para un uso personal, seleccionas una o varias carpetas, y le das al play para reproducirlas, fin de la historia xD,
pero todo lo que me habeis dicho me servirá a la hora de hacer otros programas mejores, como el USBMON que estoy intentando hacer en un WPF.

Un saludo!