Serial Port – Enumeración & Disponibilidad – Tambien en C#

 


         Saber sobre la disponibilidad de nuestros puertos serie antes de su selección en un combobox.

  How to know about availability of our computer serial ports before select one from a combo box.

A menudo las aplicaciones que requieren seleccionar un dispositivo antes de efectuar algún tipo de comunicacion, no ofrecen ninguna información adicional sobre el estado del dispositivo. Sobre todo si hablamos del puerto serie, normalmente nos ofrecen una simple enumeración de los COM. Esto último es el causante de que la aplicación nos permita seleccionar un puerto que en ocasiones no existe o está siendo usado por otro programa.

Os propongo una idea con la intención de mejorar y facilitar la selección de este tipo de dispositivos en nuestras aplicaciones.

Básicamente se trata de enumerar en un ‘ComboBox’ personalizado los puertos existentes en nuestro equipo, utilizando el mandato :

My.Computer.Ports.SerialPortNames.ToArray

En el momento de la inicialización del ‘combobox’ asignaremos el evento de ‘DrawItem’ a la función que enriquecerá el aspecto, añadiendo al nombre un rectángulo coloreado y el texto correspondiente a la disponibilidad del puerto.

AddHandler ComboBox1.DrawItem, AddressOf cmbo_SerialPorts_Status

No dudéis en contactar conmigo si necesitáis aclarar o necesitáis entender alguna parte del código.

Para poder darle mayor difusión los comentarios del código están en inglés, aunque si os parece oportuno y necesario puedo posteároslo también en español.

Sometimes our communications applications are required to select any type of external device, and normally these applications are not giving any extra information about their availability. This is the case when talk around serial ports, normally when select the port only have a simple enumeration of COM’s, this may be confusing at time leaving at users selecting inexistent ports or ports that simply are already in use.

With this sample, you can improve and make easy these device selections in our applications.

The main think is enumerate serial port inside our customized ‘ComboBox’, using :

My.Computer.Ports.SerialPortNames.ToArray

After when initialize our combo only need assign ‘DrawItem’ event to function with our personalized combo draw,

AddHandler ComboBox1.DrawItem, AddressOf cmbo_SerialPorts_Status

This function are adding red rectangle and “busy” text when no have availability, and green rectangle and “available” text when the port is free.

Please no doubt in contact with me if you need any other explanation or opinion about this.

 

 SerialEnum_Es

SerialEnum_en 


 


public partial class Form1 : Form
    {
        //Enumerate Serial Ports on Machine
        //Get Serial Port availability
        String[] Puertos = System.IO.Ports.SerialPort.GetPortNames();


 


        public Form1()


        {


            InitializeComponent();


        }


 


        private void Form1_Load(object sender, EventArgs e)


        {


            this.comboBox1.DrawMode = DrawMode.OwnerDrawVariable;       //seleccionar mi propio modo de arrastre


            this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;  //aspecto al men desplegable


            this.comboBox1.DataSource = Puertos;                        //puertos serie disponibles


            this.comboBox1.TabIndex = 0;                                //seleccione en primer lugar tabIndex


        }


 


       


        private void comboBox1_DrawItem_1(object sender, DrawItemEventArgs CmboItem)


        {


            // Dibuja el fondo del item.


            CmboItem.DrawBackground();


            // Los valores por defecto si el puerto est disponible.


            string status = “Disponible”;


            SolidBrush brush = new SolidBrush(Color.Green);


            System.Drawing.Font font = this.Font;


            Brush fontbrush = Brushes.Black;


            Rectangle rectangle = new Rectangle(2, CmboItem.Bounds.Top + 2, CmboItem.Bounds.Height – 4, CmboItem.Bounds.Height – 4);


            // Comprobar disponibilidad del puerto


            try


            {


                // Si abre y cierra los puertos sin excepcin.


                // dibuja el item con la fuente por defecto y rectngulo verde.


                System.IO.Ports.SerialPort PortTest = new System.IO.Ports.SerialPort();


                PortTest.PortName = Puertos[CmboItem.Index].ToString();


                PortTest.Open();


                PortTest.Close();


            }


            catch (Exception ex)


            {


                // Si el puerto no est disponible


                // dibuja el item con la fuente cursiva y tachado y rectngulo rojo


                brush = new SolidBrush(Color.Red);


                status = “En Uso”;


                font = new Font(FontFamily.GenericSansSerif, this.Font.Size, FontStyle.Italic ^ FontStyle.Strikeout);


                fontbrush = Brushes.DimGray;


            }


            // llenar item combo con rectangulo.


            CmboItem.Graphics.FillRectangle(brush, rectangle);


            // escribir el texto con la condicin actual del puerto de este item.


            CmboItem.Graphics.DrawString(Puertos[CmboItem.Index].ToString() + ” – “ + status, font, fontbrush, new RectangleF(CmboItem.Bounds.X + rectangle.Width, CmboItem.Bounds.Y, CmboItem.Bounds.Width, CmboItem.Bounds.Height));


            // dibujar foco del rectngulo cuando el ratn est sobre un item.


            CmboItem.DrawFocusRectangle();


        }


    }


 

17 thoughts on “Serial Port – Enumeración & Disponibilidad – Tambien en C#”

  1. disculpa tengo una duda esta parte donde va
    My.Computer.Ports.SerialPortNames.ToArray

    y esta otra
    AddHandler ComboBox1.DrawItem, AddressOf cmbo_SerialPorts_Status

    y como le hizo para obtener el combobox1_drawItem1 por favor le agradecere si resp mi duda gracias

  2. Hola PepLuis, Gracias por este código que tiene metodos que me seran muy utiles. Me gustaría saber como invocas la función comboBox1_DrawItem_1 asociado al evento de dibujar sobre el objeto comboBox1.

  3. Hola Jhonathan,

    Cuando utilices el ‘event’ ‘drawitem’ desde el diseñador de windows forms, este lo incluira directamente en la funcion ‘initialize’ del ‘form1.designer.cs’. Tambien puedes incluirlo manualmente en ‘form-load’ usando la expresion :

    this.comboBox1.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.comboBox1_DrawItem);

    Saludos,
    Pep Lluis,

  4. Hola Arnold,
    Solo tienes que crear un nuevo proyecto para Windows Form en Visual Studio, despues debes substituir el codigo del form1 por el de este ejemplo… deberia funcionar sin ningun problema en otro caso necesitaria saber si al menos estas utilizando visual studio 2005.

    Saludos,
    PepLluis,

  5. Hola PepLluis, perdón por reabrir el tema después de tanto tiempo, pero tengo un problema, estoy intentando hacer funcionar este ejemplo en visual C# 2010, y no lo consigo, tal y como tu dices, copio y pego el codigo, me da errores pero se solucionan agregando un combobox “fisico” en el Form1 “diseño”, pero cuando ejecuto el codigo, no me sale nada en el combobox, no se que me puede pasar, tienes idea??

    Muchas gracias f-traxx.

  6. Hola Adreu,
    Efectivamente te faltan dos cosas despues de copiar y pegar :
    1) Asignar el evento de “Form_load” desde las propiedades del Form
    2) despues de InicializeComponent…
    InitializeComponent();
    comboBox1.DrawItem += new DrawItemEventHandler(comboBox1_DrawItem_1);

    Con esto te funciona bien.
    Saludos,
    PepLluis,

  7. Hola Andreu,
    Para este tipo de temas deberiamos transladar la conversación al los foros. En todo caso utiliza la opción [Contact] de las opciones de la derecha, para contactar conmigo en privado y continuar con la conversación.

    Saludos,
    PepLluis,

  8. Disculpa la molestia pero dado que es un excelente ejemplo para el uso de los Puertos seriales, me gustaría saber si para hacerlo correr en un visual C# 2010 necesito agregar o modificar unas lineas del código que muestras, la verdad no tengo mucha experiencia todavía en este lenguaje.

  9. Hola, el codigo esta excelente para aplicaciones variadas, solo que me marca errores en el INDEX de la sentencia de [comboBox1.Index] y error en la parte de comboBox1.Graphics, de igual manera no me acepta el comando DrawFocus(); me faltaria agregar algo?
    Gracias

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>