Título: Obtener indice control seleccionado (Matriz 2 dimensiones) VB2013 Publicado por: Tazmania40 en 17 Enero 2019, 13:12 pm Buenas estoy realizando un programa y me veo atascado en un evento por código, de momento no encuentro nada pero sigo buscando, a ver si alguno me da la solución antes.
Pongo el siguiente ejemplo y es lo mismo que deseo que funcione con las matrices de 2 dimensiones en Visual Basic 2013. Código
El código de arriba muestra 5 controles de tipo PictureBox como un array, puesto que en NET no se podía realizar mediante diseño, al hacer click en cualquiera de ellos obtenemos el índice del que hemos pulsado y así podemos utilizar las propiedades de cada uno de ellos. Siguiendo con el ejemplo, me gustaría lo mismo para una matriz de 2 dimensiones que la dibujo perfectamente, pero cuando asigno el evento Click no se que emplear para obtener el índice puesto que Array.IndexOf es para matrices unidimensionales ¿Como puedo obtener el índice de una matriz de 2 dimensiones, (0,0) (0,1) (0,2).. (1,0)..etc, al hacer click sobre cada recuadro PictureBox ? Muchas GRACIAS y saludos Código
Título: Re: Obtener indice control seleccionado (Matriz 2 dimensiones) VB2013 Publicado por: Eleкtro en 17 Enero 2019, 23:22 pm al hacer click en cualquiera de ellos obtenemos el índice del que hemos pulsado y así podemos utilizar las propiedades de cada uno de ellos. No entiendo tu planteamiento. Si el objetivo realmente es obtener un índice con el que poder obtener acceso al control y usar sus propiedades, entonces la obtención del índice carece de sentido puesto que el objeto sender es una referencia de dicho control, pudiendo hacer algo así: Código
Para todo lo demás, una forma simple de almacenar datos adicionales (que en este caso ayuden a la identificación del control dentro de un array) sería usar la propiedad Control.Tag que hereda la clase PictureBox, ahí puedes especificar el índice y dimensión del Array o lo que tú quieras al momento de crear la instancia de dicho control en los búcles esos que tienes... Código
Pero como ya digo esto en principio no es necesario, puesto que en el controlador de eventos "Evento1" ya tienes acceso al control mediante el objeto sender. Saludos. Título: Re: Obtener indice control seleccionado (Matriz 2 dimensiones) VB2013 Publicado por: Tazmania40 en 18 Enero 2019, 10:10 am En primer lugar muchas gracias Elektro como siempre. Efectivamente el objeto sender, me fije ayer más tarde podía asignar las propiedades en el momento de hacer clic y que ese PictureBox por ejemplo cambiara de color.
Código
Aunque lo que requiero realmente es obtener el indice como en array de una dimensión. Si hay alguna forma de pasarle esas 2 coordenadas al evento o que las recoja y ponerlo en una variable matriz de 2 dimensiones Código
Como bien dices la propiedad Tag podemos guardar esas coordenadas, pero lamentablemente la utilizo para guardar valores. Otra posibilidad es agregar otra propiedad personal al control PictureBox (Como Tag, aunque claro serían otras 2 más Matriz(F, C) guardar F y C) , pero sería muy engorroso y alargaría mucho el código, además de que no se. No se si en los parámetros del evento click pueden recoger esas 2 coordenadas, tal y como hacemos cuando creamos un procedimiento o función, que también me valdría. Gracias y saludos Título: Re: Obtener indice control seleccionado (Matriz 2 dimensiones) VB2013 Publicado por: Eleкtro en 18 Enero 2019, 14:10 pm Como bien dices la propiedad Tag podemos guardar esas coordenadas, pero lamentablemente la utilizo para guardar valores. Otra posibilidad es agregar otra propiedad personal al control PictureBox (Como Tag, aunque claro serían otras 2 más Matriz(F, C) guardar F y C) , pero sería muy engorroso y alargaría mucho el código, además de que no se. La propiedad Tag es de tipo Object, lo que permite asignarle cualquier tipo de objeto, y esto quiere decir que puedes diseñar una clase como la siguiente, en la que almacenarías los datos que tu quisieras, y luego asignar una instancia de esa clase a al propiedad Tag... Código
No hace falta mencionar que en esa clase añadirías la cantidad de propiedades que realmente necesites (donde asignarías los índices del array multidimensional, entre otras cosas que desees), y del tipo que realmente sean, no necesariamente del tipo Object. Y entonces podrías hacer: Código (o lo mismo pero en el búcle del array bidimensional) ... Código
¿Eso no te sirve para las intenciones que tengas?. Esto sería más rápido que iterar los elementos de un array para hallar el control en cuestión. De todas formas, si realmente quieres encontrar el índice del control en un array multidimensional, en este ejemplo bidimensional, tan solo debes recorrer sus dimensiones, y lo puedes hacer de la siguiente manera: Código ... Código
Saludos. EDITO: Casi se me olvida mostrarte la alternativa que mencionaste de añadirle una segunda propiedad "Tag" a la clase PictureBox... Es tan simple como heredar la clase PictureBox y declarar una propiedad personalizada: Código
pero ten en cuenta que esto es un "overkill" puesto que con un propiedad tag es más que suficiente al poderle asignar cualquier tipo de objeto, y este puede ser una clase o estructura que contenga múltiples valores como ya mostré en el ejemplo de arriba. Lo que intento decir es que el pensamiento de "2 siempre es mejor que 1" en realidad resulta algo innecesario por lo que acabo de mencionar, por que la solución óptima no sería crear múltiples propiedades similares a Tag, sino en su lugar crear un tipo pesonalizado donde almacenar múltiples valores, y asignar una instancia de ese tipo a la propiedad Tag. Y por último, aquí tienes lo mismo pero con una personalización más sofisticada o cuidada para la manipulación de este PictureBox personalizado en el diseñador de forms: Código
Título: Re: Obtener indice control seleccionado (Matriz 2 dimensiones) VB2013 Publicado por: Tazmania40 en 19 Enero 2019, 00:11 am Muchas gracias Elektro eres un genio, haces que lo difícil parezca fácil y encima expones muchas maneras. Voy analizarlas y te voy escribiendo en este mismo post. No tengo mucho tiempo (tengo 3 niñas y dos son bebes) y me cuesta probar y analizar.
El primero de la clase no lo había pensado de esa manera. He realizado el código y funciona. Lo pongo el pequeño ejemplo Código
En este código la pega que veo es en Tag yo tengo valores que al principio valen 0 y luego les asigno otros al pulsar en cada recuadro que provienen de la propiedad Tag de un Picture principal. Aqui lo he llamado obj.Valor, podia solucionarlo a continuación del evento Código Vamos enredándolo un poco porque siempre tienes que pasarle todas las propiedades, pero la solución es válida para los índices de la matriz. Una pregunta para las prácticas de buena programación Friend NotInheritable : porque empleas que la clase sea Friend y este modificador (es la clase base según he leido). He probado con Public (funciona y sin modificador) que siempre realizo cuando creo mis programas, claro dentro de una clase externa. Me imagino que Friend es para que no se pueda acceder externamente, aunque ahi yo suelo emplear Private, siempre he tenido un lio con estas cosas que son sencillas. A ver si mañana (aunque ya es, jeje) pruebo la función para mi código y así conservo la propiedad Tag con los valores y sería más fácil. Gracias y saludos Título: Re: Obtener indice control seleccionado (Matriz 2 dimensiones) VB2013 Publicado por: Eleкtro en 19 Enero 2019, 07:15 am Friend NotInheritable : porque empleas que la clase sea Friend y este modificador (es la clase base según he leido). He probado con Public (funciona y sin modificador) que siempre realizo cuando creo mis programas, claro dentro de una clase externa. Me imagino que Friend es para que no se pueda acceder externamente, aunque ahi yo suelo emplear Private, siempre he tenido un lio con estas cosas que son sencillas. Realmente no tiene mucha importancia. El modificador de visibilidad de clase Friend hace que la clase solamente sea accesible desde tu proyecto/executable. Simplemente consideré que era la visibilidad de clase más acertada para tu código, puesto que el modificador Public permite acceder a la clase desde cualquier otra clase y no creo que vayas a necesitar hacer eso. El modificador de clase NotInheritable (sealed en C#) lo que hace es "sellar" la clase para que no se pueda heredar (usando el keyword Inherits como en la clase del CustomPictureBox), es decir, para que no se pueda usar como una clase base. Este sellado resulta en una pequeña optimización, así que si no tienes necesidad de heredar una clase entonces no hay problema en sellarla usando NotInheritable, pero tampoco pasa nada por no hacerlo... Aquí te dejo info acerca de las optimizaciones de usar NotInheritable:
Y las guías de diseño que recomienda Microsoft sobre el sellado de clases:
Ojo, esas recomendaciones de Microsoft parecen estar orientadas a escenarios profesionales (ej. el desarrollo de una API pública), ya que sugieren cosas como: "Sellar una clase porque no se puede pensar en un escenario de extensibilidad no es una buena razón" - pero evidentemente no puede existir un escenario de extensibilidad de tu clase "TestClass" puesto que en principio el código de esa clase sellada es solo para que lo uses tú en tu programa, así que aquí pasa a ser más que una buena razón para sellar la clase, y por ello no debes hacerle mucho caso a ciertas recomendaciones en ese sentido. Saludos. Título: Re: Obtener indice control seleccionado (Matriz 2 dimensiones) VB2013 Publicado por: Tazmania40 en 19 Enero 2019, 08:53 am Muchas gracias Elektro por todo, ya he probado la segunda opción y es la que me voy a quedar (dejo aqui el código) es justo lo que quería, por un lado con el sender obtengo las propiedades de la matriz del PictureBox donde he realizado click para cambiar y por otro lado el índice con tu función que era la pregunta principal, así conservo los datos de mi propiedad Tag que puedo modificar.
Tienes un dominio absoluto de los métodos de las clases, te envidio (sanamente) por tu facilidad sobre la programación en general, yo como ya comente en otros post programo por hobby para realizar pequeños jueguecitos principalmente con VB.NET y XNA, aunque ahora también aprendí algo de C# (traducciones a vb.net) y GameMaker (v.1.4). Gracias por la explicación de Friend, como suelo utilizar clases externas siempre pongo public. Siempre veo que sueles utilizar la forma correcta y de buenas prácticas para programar, aunque muchos no lo entendemos y dando consejos de que no utilizar. Miraré esa información a modo consulta. Sobre el tema de modificar un PictureBox o cualquier otro control, creo que es muy extenso y ese tercer método no utilizaré. Saludetes y que pases un buen finde Código
Título: Re: Obtener indice control seleccionado (Matriz 2 dimensiones) VB2013 Publicado por: Eleкtro en 19 Enero 2019, 10:02 am No quiero parecer pedante ni condescendiente ni pesado, pero no hay nada que envidiar, son cosas muy sencillitas. La manipulación de arrays (o jagged arrays) uni o multidimensionales es de las primeras cosas que se aprende a hacer si se estudia siguiendo unos pasos correctos de aprendizaje. Y el resto que he podido mostrarte como la herencia de clases o el uso de tipos genéricos pues son conceptos fundamentales de la programación orientada a objetos.
No te he mostrado nada que no pudieras llegar a hacer por ti mismo con el debido aprendizaje y la posterior práctica, pero como eres un tio de familia pues se entiende que no tengas tiempo o ganas suficiente. En fin. Un placer ayudar a personas así (de agradecidas). Saludos. |