Autor
|
Tema: (solucionado) ¿clonar evento para varios elementos? ¿FOR? (Leído 28,404 veces)
|
kub0x
Enlightenment Seeker
Moderador
Desconectado
Mensajes: 1.486
S3C M4NI4C
|
Uhm como solo te interesan los CheckBoxes tildados (Checked = TRUE) pues ponle un condicional para que sólo guarde éstos últimos. Ya me cuentas
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.885
|
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": 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: Public Sub AnyCB_CheckedChanged(sender As Object, e As EventArgs) Dim cb = DirectCast(sender, CheckBox) If cb.Checked AndAlso Not My.Settings.MyCBs.Contains(cb.Name) Then My.Settings.MyCBs.Add(cb.Name) ElseIf Not cb.Checked AndAlso My.Settings.MyCBs.Contains(cb.Name) Then My.Settings.MyCBs.Remove(cb.Name) End If End Sub Public Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown If My.Settings.MyCBs Is Nothing Then My.Settings.MyCBs = New Collections.Specialized.StringCollection For Each s In My.Settings.MyCBs DirectCast(Me.Controls(s), CheckBox).Checked = True Next For Each cb In Me.Controls.OfType(Of CheckBox)() AddHandler cb.CheckedChanged, AddressOf AnyCB_CheckedChanged Next 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"
|
|
« Última modificación: 19 Noviembre 2012, 17:29 pm por EleKtro H@cker »
|
En línea
|
|
|
|
kub0x
Enlightenment Seeker
Moderador
Desconectado
Mensajes: 1.486
S3C M4NI4C
|
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. Public Class Form1 Dim mCheck(5) As CheckBox 'matriz que contendrá los 5 CheckBox Private 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 Private 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 Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing 'Este es el evento al que se llamará cuando se cierre la aplicación 'Como ves al cerrar la aplicación llamamos al método GenerarPropiedades() para guardar los CheckBoxes que fueron tildados GenerarPropiedades() End Sub Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load For i As Int32 = 0 To mCheck.Length - 1 mCheck(i) = New CheckBox() 'creo un CheckBox en cada espacio de la matriz With mCheck(i) .Text = "Checkbox" & i + 1 ' Le adjunto un nombre Checkbox1 / Checkbox2 y 3 .Location = New Point(20, i * 30) ' Sin más los situo.... .Name = "Checkbox" & i + 1 End With Me.Controls.Add(mCheck(i)) 'Añado el control al formulario, es decir, lo dibujo Next CargarPropiedad() 'Cargo las propiedades una vez dibujados los CheckBoxes End Sub End Class
Saludos!
|
|
« Última modificación: 19 Noviembre 2012, 18:50 pm por kub0x »
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.885
|
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 : 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... Imports System.Windows.Forms Imports System.IO Public Class Form1 Dim filesystem As Object, ThisDir As Object Public newCheckBox As New CheckBox() Dim mCheck(9999) 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 Property checkedpath1() As String Get Return newCheckBox.Text End Get Set(value As String) newCheckBox.Text = value End Set End Property ' End of propertys ' update checkboxes Public Sub updatecheckboxes() ' delete the old checkboxes Panel1.Controls.Clear() ' create the new checkboxes Dim i As Int32 = 0 Dim posy As Integer = 0 Dim filesystem = CreateObject("Scripting.FileSystemObject") Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath) For Each folder In ThisDir. Subfolders i = i + 1 mCheck(i) = New CheckBox() 'creo un CheckBox en cada espacio de la matriz With mCheck(i) .Name = "Checkbox" & i ' Le adjunto un nombre Checkbox1 / Checkbox2 y 3 .Location = New Point(10, i * 20) End With 'MessageBox.Show(mCheck(i).Name) AddHandler mCheck(i).CheckedChanged, AddressOf LlamadaCheckBox 'Asocio el evento CheckedChange del CheckBox actual a la función LlamadaCheckBox Panel1.Controls.Add(mCheck(i)) Next CargarPropiedad() 'Cargo las propiedades una vez dibujados los CheckBoxes 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 Private 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 Me.Close() Next My.Settings.CuantosChecked = CheckedN 'Actualizo la propiedad My.Settings.Save() 'Guardo la propiedad End Sub ' Form close Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing 'Este es el evento al que se llamará cuando se cierre la aplicación 'Como ves al cerrar la aplicación llamamos al método GenerarPropiedades() para guardar los CheckBoxes que fueron tildados ' My.Settings.Save() GenerarPropiedades() Me.Close() 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() CargarPropiedad() 'Cargo las propiedades una vez dibujados los CheckBoxes End Sub ' Folder button Private 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
|
|
« Última modificación: 19 Noviembre 2012, 19:18 pm por EleKtro H@cker »
|
En línea
|
|
|
|
kub0x
Enlightenment Seeker
Moderador
Desconectado
Mensajes: 1.486
S3C M4NI4C
|
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. Dim mCheck(0) as CheckBox() 'un indice Private Sub BuscarCarpetas() Dim i as integer = 0 for directorio in subdirectorios i+=1 'se encontró una carpeta, sumo un indice Array.Resize(mCheck,i) 'meto un indice mas a la matriz de CheckBoxes for i as int32 = 0 to mCheck.length - 1 mCheck(i) = New CheckBox() 'y aqui sigues como esta Next
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!
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.885
|
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? Dim filesystem = CreateObject("Scripting.FileSystemObject") Dim ThisDir = filesystem.GetFolder(My.Settings.folderpath) Dim folderindex As Integer = 0 For Each folder In ThisDir. Subfolders folderindex += 1 Array.Resize(mCheck, folderindex) Next For i As Int32 = 0 To mCheck.Length - 1 mCheck(i) = New CheckBox() With mCheck(i) .Name = "Checkbox" & i .Location = New Point(10, i * 20) End With 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: 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) 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" .
|
|
« Última modificación: 19 Noviembre 2012, 20:40 pm por EleKtro H@cker »
|
En línea
|
|
|
|
kub0x
Enlightenment Seeker
Moderador
Desconectado
Mensajes: 1.486
S3C M4NI4C
|
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
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.885
|
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 ' 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 = 0 For Each folder In ThisDir. Subfolders i += 1 Array.Resize(mCheck, i) MessageBox.Show("test") mCheck(i) = New CheckBox() With mCheck(i) .Name = "Checkbox" & i .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 Panel1.Controls.Add(mCheck(i)) Next CargarPropiedad() 'Cargo las propiedades una vez dibujados los CheckBoxes End Sub
Tengo declarado el mcheck así como me dijiste: Dim mCheck(0) As CheckBox PD: El messagebox solo se muesta UNA vez :S Muchas gracias por tu tiempo
|
|
« Última modificación: 19 Noviembre 2012, 21:22 pm por EleKtro H@cker »
|
En línea
|
|
|
|
HdM
Desconectado
Mensajes: 1.674
|
Hola EleKtro. El problema lo tienes aquí: 'al incrementar la variable i, no estas inicializando el 1er elemento del array (indice=0) i += 1 Array.Resize(mCheck, i) MessageBox.Show("test") mCheck(i) = New CheckBox() With mCheck(i)
Prueba poniendo todas las referencias a i cuando actúa como índice dentro del bucle, como i-1. Saludos.
|
|
|
En línea
|
- Nice to see you again -
|
|
|
kub0x
Enlightenment Seeker
Moderador
Desconectado
Mensajes: 1.486
S3C M4NI4C
|
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!
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Crear copia para clonar en varios PCs?
GNU/Linux
|
JJMD
|
1
|
2,309
|
28 Febrero 2013, 23:09 pm
por portaro
|
|
|
Problema con un JMenuItem, no escucha evento de mouse (ya Solucionado)
Java
|
DarkSorcerer
|
1
|
3,289
|
23 Julio 2013, 12:19 pm
por Debci
|
|
|
Comparar checkbox con varios elementos
Programación Visual Basic
|
rapbyone
|
4
|
2,304
|
12 Febrero 2016, 18:50 pm
por fary
|
|
|
WhatsApp añade más elementos para usar la app en varios móviles a la vez
Noticias
|
wolfbcn
|
0
|
1,117
|
15 Noviembre 2019, 14:47 pm
por wolfbcn
|
|
|
¿Existe algún algoritmo para escribir las pemutaciones de n elementos sin almacenar las de n-1 elementos?
Programación General
|
fzp
|
3
|
5,359
|
24 Octubre 2021, 23:06 pm
por fzp
|
|