Buenas tardes, ahora estoy batallando un poco con un control nuevo que estoy creando. Se trata de un modulo de led para una pantalla. Lo que quiero es dibujar en el el texto que ya tengo descompuesto en pixeles de acuerdo a la resolucion de la pantalla. Para eso quiero poder llamar un metodo (desde un proyecto que use el nuevo control) que hagan referencia a cada pixel de cada modulo para decidir si mostrar la imagen de apagado o encendido.
En si lo que busco es un buen tutorial acerca de como crear un usercontrol y definir sus metodos y eventos para que pueda utilizarlos como cualquier otro control de windows.
el código es el siguiente:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace Modulo
{
public partial class ModLed : UserControl
{
private ArrayControles<PictureBox> m_pixel;
public ModLed()
{
InitializeComponent();
m_pixel = new ArrayControles<PictureBox>("pixel", this);
asignar();
}
private void PCB_Click(object sender, EventArgs e)
{
}
private void asignar()
{
foreach (PictureBox pixel in m_pixel)
{
pixel.Click += pixel_Click;
}
}
public void pixel_Click(object sender, EventArgs e)
{
int index = m_pixel.Index(sender);
m_pixel[index].Image = Properties.Resources.enc;
}
}
}
y estoy usando una clase arreglo para manipular los leds
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
namespace Modulo
{
/// <summary>
/// Clase para contener controles del tipo indicado,
/// que debe derivarse de Control.
/// </summary>
/// <typeparam name="T">
/// El tipo de control que contendrá la colección.
/// </typeparam>
/// <remarks>
/// Se deriva de List<T>
/// </remarks>
public class ArrayControles<T> : List<T>
where T : Control
{
private string m_Nombre;
/// <summary>
/// En el constructor se debe indicar el nombre del control.
/// </summary>
/// <param name="elNombre">
/// El nombre base de los controles del array,
/// esos controles deben tener el nombre: elNombre_numero.
/// No se admite una cadena vacía.
/// </param>
/// <remarks></remarks>
public ArrayControles(string elNombre)
: base()
{
if (String.IsNullOrEmpty(elNombre))
{
throw new ArgumentException(
"El nombre del control no puede ser una cadena vacía");
}
// Asignarlo a la propiedad
// para que se convierta en minúsculas
// o cualquier otra comprobación.
this.Nombre = elNombre;
}
/// <summary>
/// Constructor para inicializar directamente la colección de controles
/// </summary>
/// <param name="ctrls">
/// Colección de controles en la que están los que debemos usar.
/// </param>
/// <param name="elNombre">
/// El nombre base de los controles a tener en cuenta.
/// </param>
/// <remarks></remarks>
public ArrayControles(
string elNombre,
Control.ControlCollection ctrls)
: this(elNombre)
{
//
this.Clear();
asignarLosControles(ctrls);
this.Reorganizar();
}
/// <summary>
/// Constructor para inicializar directamente la colección de controles
/// </summary>
/// <param name="contenedor">
/// El contenedor que tiene los controles a comprobar.
/// </param>
/// <param name="elNombre">
/// El nombre base de los controles a tener en cuenta.
/// </param>
/// <remarks></remarks>
public ArrayControles(
string elNombre,
ContainerControl contenedor)
: this(elNombre, contenedor.Controls)
{
}
/// <summary>
/// Asignar los controles de la colección indicada.
/// </summary>
/// <param name="ctrls">
/// Colección de controles en la que están los que debemos usar.
/// El nombre usado será el indicado al crear la colección.
/// </param>
/// <remarks>
/// La colección de controles puede ser Me.Controls
/// ya que aquí solo se tendrán en cuenta los controles
/// que tengan el nombre usado en esta clase,
/// y se recorren todas las colecciones de controles que haya.
/// </remarks>
public void AsignarControles(Control.ControlCollection ctrls)
{
this.Clear();
asignarLosControles(ctrls);
this.Reorganizar();
}
/// <summary>
/// Asignar los controles del contenedor indicado.
/// </summary>
/// <param name="contenedor">
/// El contenedor de los controles en los que se buscarán
/// los del tipo indicado en esta colección.
/// </param>
/// <remarks></remarks>
public void AsignarControles(ContainerControl contenedor)
{
this.Clear();
asignarLosControles(contenedor.Controls);
this.Reorganizar();
}
private void asignarLosControles(Control.ControlCollection ctrls)
{
// El tipo debe ser Control, para tener en cuenta todos los controles
// que haya en la colección indicada.
foreach (Control ctr in ctrls)
{
// Hacer una llamada recursiva por si este control "contiene" otros
if (ctr.Controls.Count > 0)
{
asignarLosControles(ctr.Controls);
}
// No tener en cuenta las mayúsculas o minúsculas
if (ctr.Name.ToLower().IndexOf(m_Nombre) > -1)
{
this.Add(ctr as T);
}
}
}
// Sobrecargas de la propiedad predeterminada
/// <summary>
/// Propiedad predeterminada para devolver
/// el control con el nombre indicado.
/// </summary>
/// <param name="name">
/// El nombre del control a buscar.
/// </param>
/// <value></value>
/// <returns>
/// El control que tiene el nombre indicado.
/// </returns>
/// <remarks></remarks>
public T this[string name]
{
get
{
int index = this.Index(name);
// Si existe, devolverlo, sino, devolver un valor nulo
if (index == -1)
{
return null;
}
return this[index];
}
}
/// <summary>
/// Sobrecarga de la propiedad predeterminada
/// para permitir el acceso con un valor de tipo Object.
/// Aunque el tipo debe ser del que contiene la colección,
/// si no es así, se devuelve un valor nulo.
/// </summary>
/// <param name="obj">
/// El control a comprobar
/// </param>
/// <value></value>
/// <returns>
/// Si el parámetro es del tipo adecuado,
/// se devuelve con el tipo de la colección,
/// si no lo es, se devuelve un valor nulo.
/// </returns>
/// <remarks></remarks>
public T this[object obj]
{
get
{
// En C# cuando el parámetro es int
// la sobrecarga de object tiene preferencia.
if (obj.GetType() == typeof(int))
{
return base[(int)obj];
}
T ctrl = obj as T;
return ctrl;
}
}
/// <summary>
/// Devuelve el índice del control de esta colección
/// que tenga el mismo índice que el del parámetro.
/// Ese parámetro puede ser cualquier control,
/// y lo que se tendrá en cuenta será el nombre usado,
/// el cual debe tener la forma nombre_indice,
/// de forma que se devolverá el control que tenga ese mismo índice.
/// </summary>
/// <param name="obj">
/// El control a comprobar si existe un índice como el indicado.
/// Al ser de tipo Object no es necesario que sea del mismo tipo
/// que los que contiene esta colección.
/// </param>
/// <returns>
/// El índice correspondiente.
/// Aunque no se comprueba si existe en la colección.
/// En el caso de que el parámetro no tenga el formato adecuado,
/// se devuelve -1.
/// </returns>
/// <remarks>
/// Esta sobrecarga se puede usar para buscar el control correspondiente
/// con el del índice de otro control, por ejemplo:
/// i = m_TextBox1.Index(sender)
/// Por supuesto, el parámetro debe ser de tipo Control.
/// Este método podría estar compartido, pero debido a que su uso
/// sería: ArrayControles<TIPO>.Index(sender)
/// he preferido dejarlo como de instancia.
/// </remarks>
public int Index(object obj)
{
Control ctrl = obj as Control;
if (ctrl == null)
{
return -1;
}
//
int i = -1;
i = ctrl.Name.LastIndexOf("_");
if (i > -1)
{
i = Convert.ToInt32(ctrl.Name.Substring(i + 1));
}
return i;
}
/// <summary>
/// Devuelve el índice del control con el nombre indicado.
/// </summary>
/// <param name="name">
/// Nombre del control a buscar en la colección.
/// </param>
/// <returns>
/// Un valor de tipo entero con el índice del control.
/// </returns>
/// <remarks></remarks>
public int Index(string name)
{
int hallado = -1;
for (int i = 0; i < this.Count; i++)
{
T ctrl = this
;
if (String.Compare(ctrl.Name, name, true) == 0)
{
hallado = i;
break;
}
}
return hallado;
}
/// <summary>
/// Devuelve el índice del control indicado.
/// </summary>
/// <param name="ctrl">
/// El control del que queremos averiguar el índice.
/// </param>
/// <returns>
/// Un valor de tipo entero con el índice del control.
/// </returns>
/// <remarks></remarks>
public int Index(T ctrl)
{
int i = ctrl.Name.LastIndexOf("_");
//
// Si el nombre no tiene el signo _
if (i == -1)
{
i = this.IndexOf(ctrl);
}
else
{
i = Convert.ToInt32(ctrl.Name.Substring(i + 1));
}
return i;
}
//
/// <summary>
/// La propiedad Nombre, externamente será de solo lectura.
/// </summary>
/// <value>El nombre de la colección de controles</value>
/// <returns>
/// El nombre de la colección de controles.
/// </returns>
/// <remarks>
/// </remarks>
public string Nombre
{
get
{
return m_Nombre;
}
private set
{
m_Nombre = value.ToLower();
}
}
//
/// <summary>
/// Reorganizar el contenido de la colección,
/// ordenando por el índice indicado después del guión bajo
/// </summary>
/// <remarks></remarks>
public void Reorganizar()
{
List<T> ca = new List<T>();
//
for (int i = 0; i < this.Count; i++)
{
foreach (T ctr in this)
{
if (i == this.Index(ctr))
{
ca.Add(ctr);
break;
}
}
}
//
this.Clear();
foreach (T ctr in ca)
{
this.Add(ctr);
}
}
}
}