none
Concatenar dos ListView en uno solo RRS feed

  • Pregunta

  • Buenas noches a todos, esta es mi primer pregunta en la cual quisiera me puedan brindar apoyo.

    Les platico, tengo tres listView en mi formulario en el listViewA obtengo los registros de un sp de SqlServer y muestro los datos en el listViewA.

    ListViewB, este lo llena el usuario en tiempo ejecución y la cantidad de filas es igual a la cantidad de fila del listViewA.

    El problema es, que quiero concatenar ambos listView con un tercero, para ello estoy usando ArrayList pero no lo estoy obteniendo.

    Adjunto una imagen para que sea un poco mas entendible lo que pretendo, listView A y listViewB es lo que tengo y quiero obtener un tercer listView como el C.

    Este es el código que tengo:

    Para cargar el listView A:

    private void cargaListaA()
            {
                try
                {
                    SqlCommand cmd = new SqlCommand("Aprendizaje", cnx);
                    cmd.CommandType = CommandType.StoredProcedure;
                    SqlDataAdapter da = new SqlDataAdapter(cmd);
                    DataTable dt = new DataTable();
                    da.SelectCommand.CommandType = CommandType.StoredProcedure;
                    da.SelectCommand.Parameters.AddWithValue("@Id", cmbSelectApp.SelectedValue);
                    da.Fill(dt);
                    listA.Clear();
                    listA.CheckBoxes = true;
                    listA.Columns.Add(dt.Columns[0].ToString(), 40);
                    listA.Columns.Add(dt.Columns[1].ToString(), );
                    listA.Columns.Add(dt.Columns[2].ToString(), 60);
                    listA.Columns.Add(dt.Columns[3].ToString(), 60);
                    listA.Columns.Add(dt.Columns[4].ToString(), 60);
                    listA.Columns.Add(dt.Columns[5].ToString(), 60);
    
                    foreach (DataRow row in dt.Rows)
                    {
                        string[] arr = new string[7];
                        ListViewItem itm = new ListViewItem();
    
                        for (int ncol = 0; ncol < 7; ncol++)
                        {
                            arr[ncol] = row[ncol].ToString();
                            itm = new ListViewItem(arr);
                        }
                        listA.Items.Add(itm);
                    }
                    cnx.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

    Con este metodo lleno el segundo listView en tiempo ejecución:

    private void obtenControl(string txt)
            {
                string[] lineItems = txt.Split('-');
                listB.CheckBoxes = true;
                lv = new ListViewItem(txt);
                lv.Text = lineItems[0];
                lv.SubItems.Add(lineItems[1]);
                lv.SubItems.Add(lbl_x.Text.ToString());
                lv.SubItems.Add(lbl_y.Text.ToString());
                listB.Items.Add(lv);
                count = count + 1;
                lblItems.Text = "Eventos totales: " + count.ToString();
            }
    
            public void MouseMoved(object sender, MouseEventArgs e)
            {
                lbl_x.Text = e.Location.X.ToString();
                lbl_y.Text = e.Location.Y.ToString();
    
                if (e.Clicks > 0)
                    obtenControl("Mouse - " + e.Button.ToString());
            }

    Y con este otro código quiero llenar el tercer listView, pero lo que hace es llenarme con el numero del Id de la primera lista  

    private void button1_Click(object sender, EventArgs e)
            {
                if (listA.Items.Count > 0 || listB.CheckedItems.Count > 0)
                {
                    try
                    {
                        ArrayList aList = new ArrayList();
                        ArrayList bList = new ArrayList();
    
    
                        string delimiter = ";";
                        for (int i = 0; i < listA.Items.Count - 1; i++)
    
                        {
                            string columns = String.Empty;
                            columns += listA.Items[i].Text + delimiter;
                            columns += listA.Items[i].Text + delimiter;
                            columns += listA.Items[i].Text + delimiter;
                            columns += listA.Items[i].Text + delimiter;
                            columns += listA.Items[i].Text + delimiter;
                            columns += listA.Items[i].Text + delimiter;
                            columns += listA.Items[i].Text + delimiter;
    
                            aList.Add(columns);
                        }
    
                        for (int i = 0; i < listB.Items.Count - 1; i++)
                        {
                            string columns = String.Empty;
                            columns += listB.Items[i].Text + delimiter;
                            columns += listB.Items[i].Text + delimiter;
                            columns += listB.Items[i].Text + delimiter;
                            columns += listB.Items[i].Text;
                            bList.Add(columns);
    
                            aList.AddRange(bList);//Concatenacion de ambos Arraylist, si es correcto esto?
                        }
    
                        //***Bloque para insertar los valores al ListView***//
    
                        foreach (string line in aList)
                        {
                            string[] split = line.Split(';');
    
                            if (split.Length > 0)
                            {
    
                                for (int i = 0; i < split.Length; i++)
                                {
                                    ListViewItem lvi = new ListViewItem(split[i]);
                                    lvi.SubItems.Add(split[i]);
                                    listC.Items.Add(lvi);
                                    lvi = new ListViewItem();
                                }
                            }
                            lblItems.Text = listC.Items.Count.ToString();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                else
                {
                    MessageBox.Show("Lista vacia");
                }
            }

    Espero me puedan ayudar con este problema, Erick.

    Aqui dejo las imagenes ya que no las pude subir al foro.:

    https://ibb.co/fXbj3bS

    Esto es lo que me esta haciendo:
    https://ibb.co/10nRc69
    • Editado Erick SolR viernes, 2 de octubre de 2020 6:05
    viernes, 2 de octubre de 2020 5:39

Respuestas

  • Hola Erick

    Tu código se parece bastante al de una pregunta de Dany Solis.

    Lo que tendrías que hacer es, 1° que el ListView C tenga todas las columnas para recibir los items de A y B; 2°, en lugar de tener 2 for, tener uno solo en el que le asignas (por cada fila o Item) los SubItems de A y luego los de B, con lo cual tendrías sólo un ArrayList (hoy en día se usa List<Tipo> que es genérico, ya no ArrayList). 

    Ahora que veo tu código más detenidamente, en aList, iteras pero no accedes a cada columna, sino a toda la fila:

    listA.Items[i]

    lo cual parece que te devuelve sólo la 1ra columna (según vos decis, el Id). A las columnas podes acceder con la propiedad SubItems de cada fila o Item.

    y le asignas eso (el Id) al string columns en todas sus partes (separadas por el caracter ; )

    El código correcto podría ser (supone que ListC tiene la cantidad de columnas de ListA más la de ListB, y que ListA y ListB tienen la misma cantidad de filas o Items): 

    string[] columnas;
    int a, b, i;
    for (i = 0; i < listA.Items.Count; i++)
    {
        columnas = new string[listA.Columns.Count + listB.Columns.Count];
        for (a = 0; a < listA.Columns.Count; a++)
            columnas[a] = listA.Items[i].SubItems[a].Text;
        for (b = 0; b < listB.Columns.Count; b++, a++)
            columnas[a] = listB.Items[i].SubItems[b].Text;
        listC.Items.Add(new ListViewItem(columnas));
    }
    

    No lo probé pero creo que debería funcionar. Si no, seguimos intentando.

    Saludos

    Pablo


    • Marcado como respuesta Erick SolR sábado, 3 de octubre de 2020 6:19
    viernes, 2 de octubre de 2020 15:49

Todas las respuestas

  • Hola Erick SolR, 

      

    Gracias por levantar tu consulta en los foros de MSDN. Entendimos su pregunta y vamos a darle seguimiento para buscar la mejor repuesta pertinente al caso.  

    Gracias por usar los foros de MSDN.   

     

     Andres Aguilar

     ____________________________ 

      

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde.

    Si tiene algún cumplido o reclamo sobre el soporte de MSDN sientase en la libertad de contactar  MSDNFSF@microsoft.com. 

     

    viernes, 2 de octubre de 2020 14:29
    Moderador
  • Hola Erick

    Tu código se parece bastante al de una pregunta de Dany Solis.

    Lo que tendrías que hacer es, 1° que el ListView C tenga todas las columnas para recibir los items de A y B; 2°, en lugar de tener 2 for, tener uno solo en el que le asignas (por cada fila o Item) los SubItems de A y luego los de B, con lo cual tendrías sólo un ArrayList (hoy en día se usa List<Tipo> que es genérico, ya no ArrayList). 

    Ahora que veo tu código más detenidamente, en aList, iteras pero no accedes a cada columna, sino a toda la fila:

    listA.Items[i]

    lo cual parece que te devuelve sólo la 1ra columna (según vos decis, el Id). A las columnas podes acceder con la propiedad SubItems de cada fila o Item.

    y le asignas eso (el Id) al string columns en todas sus partes (separadas por el caracter ; )

    El código correcto podría ser (supone que ListC tiene la cantidad de columnas de ListA más la de ListB, y que ListA y ListB tienen la misma cantidad de filas o Items): 

    string[] columnas;
    int a, b, i;
    for (i = 0; i < listA.Items.Count; i++)
    {
        columnas = new string[listA.Columns.Count + listB.Columns.Count];
        for (a = 0; a < listA.Columns.Count; a++)
            columnas[a] = listA.Items[i].SubItems[a].Text;
        for (b = 0; b < listB.Columns.Count; b++, a++)
            columnas[a] = listB.Items[i].SubItems[b].Text;
        listC.Items.Add(new ListViewItem(columnas));
    }
    

    No lo probé pero creo que debería funcionar. Si no, seguimos intentando.

    Saludos

    Pablo


    • Marcado como respuesta Erick SolR sábado, 3 de octubre de 2020 6:19
    viernes, 2 de octubre de 2020 15:49
  • Muchas gracias por tu ayuda.

    Probé tu código y me ha funcionado, para unir los dos listView como le esperaba.

    Acerca del punto No2, ya no seria necesario o seria una mejora del código?

    Erick.

    sábado, 3 de octubre de 2020 6:18
  • Hola

    No entiendo bien. Qué no sería necesario? Tener 2 for?

    No, no es necesario, aunque se podría hacer con 2 for, es mucho más fácil, corto, y legible hacerlo con uno solo.

    Saludos

    Pablo

    sábado, 3 de octubre de 2020 12:15
  • Hola Erick SolR

    Gracias por confirmar que se ha encontrado una solución a la consulta realizada. Debido a ello, este hilo será cerrado. 

    Si es necesario, por favor abra un nuevo hilo. 

    Gracias por usar los foros de MSDN. 

     

     Andres Aguilar

    ____________________________ 

      

    lunes, 5 de octubre de 2020 16:30
    Moderador