Corregir o quitar elementos del comBoBox

Iniciado por Meta, 6 Abril 2021, 19:33 PM

0 Miembros y 1 Visitante están viendo este tema.

K-YreX

Claro, entonces el problema estaba en que no se estaba guardando en <datos> todas las unidades sino que se van sobreescribiendo en cada iteración. Entonces tienes que concatenar todo y preferiblemente como dice Serapis añadiendo un espacio entre cada unidad para separarlos mediante el espacio y mantener los dos puntos...
Código (csharp) [Seleccionar]

datos += mj[syntax].ToString() + " ";
...
string[] unidades = datos.Split(' ');
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

Meta

Funciona mejor, casi perfecto.  ;-) ;-) ;-) ;-) ;-) ;-)

Ahora pone:
G:
F:
Espacio enblanco

No se que pinta en el último elemento un espacio en blanco, queda feo.

Solo hace falta corregir ese último detalle.

Lo demás, perfecto.

:silbar: :silbar: :silbar: :silbar: :silbar:
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Danielㅤ

#12
Hola, si aparece una línea vacía al final del combobox debe ser porque hay un salto de línea al final del string, algo como:

C:D:E:F:\n

o también puede ser porque el Split no está operando como debería o puede que el código esté detectando una unidad que no existe.


Saludos
¡Regresando como cual Fenix! ~
Bomber Code © 2021 https://www.bombercode.net/foro/

Ayudas - Aportes - Tutoriales - Y mucho mas!!!

Meta

Buenas gente:

Desde que llegue en el depurador hasta aquí indicado.

Código (csharp,8) [Seleccionar]
        void UnidadDisco()
        {
            // Nombre de la unidad.
            ConsigueComponentes("Win32_CDROMDrive", "Id");
           
            // Delimitador.
            string[] unidad = datos.Split(' ');
            comboBox_Unidad.Items.AddRange(unidad);
           

            //comboBox_Unidad.Items.AddRange(unidades.Split(':'));  //el Split se puede hacer en una sola linea.

            // Selecciona la primera unidad.
            comboBox_Unidad.SelectedIndex = 0;
        }


Se añade un espacio por la cara.


Saludos.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Danielㅤ

Hola, prueba a poner al final del Split:

System.StringSplitOptions.RemoveEmptyEntries

o

StringSplitOptions.RemoveEmptyEntries

Eso lo tenés que poner como parámetro en tu Split();.


Saludos
¡Regresando como cual Fenix! ~
Bomber Code © 2021 https://www.bombercode.net/foro/

Ayudas - Aportes - Tutoriales - Y mucho mas!!!

K-YreX

Exactamente, como dice [D]aniel se soluciona.
Como estás añadiendo un espacio después de cada unidad, te queda una cadena como esta (sustituyo cada espacio por un _):

datos = "G:_F:_"
Primer Split -> "G:" (parte izquierda) + "F:_" (parte derecha)
Segundo Split -> "G:" + "F:" (parte izquierda) + "" (parte derecha)

Por eso al final queda un último elemento que es una cadena vacía. Porque es lo que queda a la derecha del último espacio.

Otra solución válida es:
Código (csharp) [Seleccionar]

datos = ... // datos = "G:_F:_"
datos = datos.Trim(); // Elimina espacios iniciales y finales -> datos = "G:_F:"
string[] unidades = datos.Split(' ');
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

Meta

Funciona.
Código (csharp) [Seleccionar]
        void UnidadDisco()
        {
            // Nombre de la unidad.
            ConsigueComponentes("Win32_CDROMDrive", "Id");

            datos = datos.Trim();

            // Delimitador.
            string[] unidad = datos.Split(' ');
            comboBox_Unidad.Items.AddRange(unidad);
           

            //comboBox_Unidad.Items.AddRange(unidades.Split(':'));  //el Split se puede hacer en una sola linea.

            // Selecciona la primera unidad.
            comboBox_Unidad.SelectedIndex = 0;
        }


Me he dado cuenta que en el otro programa más grande no.

Ya no me dice si tiene disco o no.
Código (csharp) [Seleccionar]
using System;
using System.Management; // No olvidar y añadir en Dependencias, NuGet.
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace Lector_discos_Net_5_01_cs
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // Variable.
        string datos = "";

        [DllImport("winmm.dll")]
        public static extern Int32 mciSendString(string lpstrCommand,
            StringBuilder lpstrReturnString,
            int uReturnLength,
            IntPtr hwndCallback);

        StringBuilder rt = new StringBuilder(127);

        private void button_Abrir_Click(object sender, EventArgs e)
        {
            label_Mensaje.Text = "Abriendo...";
            Application.DoEvents();
            mciSendString("set CDAudio!" + comboBox_Unidad.Text + " door open", rt, 127, IntPtr.Zero);

            /*
               Si quieres por ejemplo elegir la unidad que quieras, en este caso la H, se le asigana !H
               como indica abajo. En vez de CDAudio, CDAudio!H.
               mciSendString("set CDAudio!H door open", rt, 127, IntPtr.Zero);
            */

            label_Mensaje.Text = "Abierto.";
            discoSiNo();
        }

        private void button_Cerrar_Click(object sender, EventArgs e)
        {
            label_Mensaje.Text = "Cerrando...";
            Application.DoEvents();
            mciSendString("set CDAudio!" + comboBox_Unidad.Text + " door closed", rt, 127, IntPtr.Zero);
            label_Mensaje.Text = "Cerrado.";
            label_Mensaje_disco.Text = "Disco en el lector: Leyendo...";
            discoSiNo();
        }

        // Lectura de dispositivos.
        void ConsigueComponentes(string hwclass, string syntax)
        {
            ManagementObjectSearcher mos = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + hwclass);
            foreach (ManagementObject mj in mos.Get())
            {
                if (Convert.ToString(mj[syntax]) != "")
                {
                    //datos = Convert.ToString(mj[syntax]);
                    datos += Convert.ToString(mj[syntax]).ToString() + " ";
                }
            }
        }

        // Comprobar si hay disco en el lector.
        void discoSiNo()
        {
            // Disco en la unidad del lector.
            ConsigueComponentes("Win32_CDROMDrive", "MediaLoaded");

            // ¿Disco en el lector?
            if (datos == "True")
            {
                label_Mensaje_disco.Text = "Disco en el lector: Sí.";
            }

            else
            {
                label_Mensaje_disco.Text = "Disco en el lector: No.";     
            }

            // Limpiar.
            datos = "";
           

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            discoSiNo();

            // Nombre de la unidad.
            ConsigueComponentes("Win32_CDROMDrive", "Id");

            // Borra espacios en blanco.
            datos = datos.Trim();

            // Delimitador.
            string[] unidad = datos.Split(' ');
            comboBox_Unidad.Items.AddRange(unidad);


            // Selecciona la primera unidad.
            comboBox_Unidad.SelectedIndex = 0;

            // Limpiar.
            datos = "";
        }
    }
}
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

K-YreX

Normal que en el segundo código no funcione si estás intentando comparar el contenido de <datos> a "True" (línea 74) cuando no estás guardando "True". Y tú me dirás que sí, que en la línea 71 llamas a la función y guarda "True" en <datos> pero entonces yo te diré "y qué pasa con el espacio que estás añadiendo al final?? (línea 62)"

Por otra parte decir que ese código tiene demasiado acoplamiento. Utilizas todo el tiempo la misma variable <datos> para guardar cada uno de los resultados. Es mejor que la función devuelva un string con el resultado y ya tú lo asignarás a la variable que quieras en cada momento.

Una mejor opción sería algo como esto:
Código (csharp) [Seleccionar]

private static readonly char SEPARADOR = "|"; // Separador de elementos. Por si en algun momento necesitas cambiarlo por otro

private string ConsigueComponentes(string hwclass, string syntax) {
    string resultado = string.Empty;
    ManagementObjectSearcher mos = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + hwclass);
    foreach (ManagementObject mj in mos.Get()) {
        if (!string.IsNullOrEmpty(mj[syntax].ToString()))
            resultado += mj[syntax].ToString() + SEPARADOR;
    }
    // El ultimo separador nunca lo vas a necesitar para nada -> Lo puedes eliminar directamente y quitarte futuros problemas
    resultado = resultado.Remove(resultado.Length - 1);
    return resultado;
}

// Mejor tener un metodo que te diga si hay o no hay disco con true/false y luego ya lo usaras donde lo necesites
private bool HayDisco() {
    string resultado = ConsigueComponentes(...);
    return (resultado == "True");
}

private void Form_Load(object sender, EventArgs e) {
    ...
    string[] unidades = ConsigueComponentes(...).Split(SEPARADOR);
    comboBox.Items.AddRange(unidades);
    ...
}
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;