Popular datagridview com um array C#

Tenho uma variável contendo dentro dela strings;

 var array = records.Split(new string() { ","}, StringSplitOptions.RemoveEmptyEntries);

Para percorrer e preencher o datagridview com este array estou usando o seguinte código

 foreach (var dado in array)
 {                        
    int index = tableLeitura.Rows.Add(dado);
    tableLeitura.Rows(index).Cells(0).Value = dado;
 }

Porém, todos os dados estão sendo colocados na primeira coluna… O datagridview tem 11 colunas, como eu poderia distribuir essas strings em todas colunas e não somente na primeira?

Agradeço qualquer ajuda ou dica.

object oriented – DataGridView Undo/Redo Manager in C#

While answering this code review question, I proposed a solution with List<DataTable>. I am trying to encapsulate this data structure into a “DataGridView Undo/Redo Manager” class DataGridViewManager and there are several build-in methods including IsUndoable, IsRedoable, Push, Redo, Undo, etc. The following methods are implemented.

  • IsUndoable method handles the process for checking if the previous states is available.
  • IsRedoable method handles the process for checking if the next states is available.
  • Push method handles the process for pushing new states.

The experimental implementation

The experimental implementation of DataGridViewManager is as below.

class DataGridViewManager
{
    Stack<DataTable> dtStack = new Stack<DataTable>();
    private int RecordIndex = 0;

    public DataGridViewManager()
    { }

    public DataGridViewManager Push(DataTable dataTable)
    {
        ClearUnnecessaryHistory();
        this.dtStack.Push(dataTable);
        return this;
    }

    public DataTable Redo()
    {
        return dtStack.ToList()(--RecordIndex);
    }

    public DataTable Undo()
    {
        return dtStack.ToList()(++RecordIndex);
    }

    public DataTable GetCurrentState()
    {
        return dtStack.ElementAt(RecordIndex);
    }

    public bool IsUndoable()
    {
        if (RecordIndex == this.dtStack.Count - 1)
            return false;
        else
            return true;
    }

    public bool IsRedoable()
    {
        if (RecordIndex == 0)
            return false;
        else
            return true;
    }

    private void ClearUnnecessaryHistory()
    {
        while (RecordIndex > 0)
        {
            dtStack.Pop();
            RecordIndex--;
        }
        return;
    }
}

Test cases

The usage of DataGridViewManager class is like:

public partial class Form1 : Form
{
    DataGridViewManager DataGridViewManager1 = new DataGridViewManager();

    public Form1()
    {
        InitializeComponent();

        //    Construct Columns
        dataGridView1.ColumnCount = 1;
        dataGridView1.Columns(0).Name = "0";

        dataGridView1.Rows.Add(20);// Add row

        DataGridViewManager1.Push(GetDataTableFromDGV(dataGridView1));
        UpdateBtnStatus();
    }

    public DataTable GetDataTableFromDGV(DataGridView dgv)
    {
        var dt = new DataTable();

        foreach (DataGridViewColumn column in dgv.Columns)
        {
            dt.Columns.Add(column.Name);
        }

        object() cellValues = new object(dgv.Columns.Count);

        foreach (DataGridViewRow row in dgv.Rows)
        {
            for (int i = 0; i < row.Cells.Count; i++)
            {
                cellValues(i) = row.Cells(i).Value;
            }
            dt.Rows.Add(cellValues);
        }
        return dt;
    }

    public void datatablaToDataGrid(DataGridView dgv, DataTable datatable)
    {
        for (int i = 0; i < datatable.Rows.Count; i++)
        {
            for (int j = 0; j < datatable.Columns.Count; j++)
            {
                dgv.Rows(i).Cells(j).Value = datatable.Rows(i)(j).ToString();
            }
        }
    }

    private void UpdateBtnStatus()
    {
        btn_Redo.Enabled = DataGridViewManager1.IsRedoable();
        btn_Undo.Enabled = DataGridViewManager1.IsUndoable();
        return;
    }

    private void btn_Undo_Click(object sender, EventArgs e)
    {
        datatablaToDataGrid(dataGridView1, DataGridViewManager1.Undo());
        UpdateBtnStatus();
    }

    private void btn_Redo_Click(object sender, EventArgs e)
    {
        datatablaToDataGrid(dataGridView1, DataGridViewManager1.Redo());
        UpdateBtnStatus();
    }

    private void dataGridView1_CellValidated(object sender, DataGridViewCellEventArgs e)
    {
        UpdateBtnStatus();

        DataGridView dgv = (DataGridView)sender;
        int r = e.RowIndex;
        int c = e.ColumnIndex;
        if (dgv.Rows(r).Cells(c).Value != null)
        {
            string dgvResult = dgv.Rows(r).Cells(c).Value.ToString();
            string dtResult = DataGridViewManager1.GetCurrentState().Rows(r)(c).ToString();
            if (dgvResult != dtResult)
            {
                DataGridViewManager1.Push(GetDataTableFromDGV(dataGridView1));
            }
        }
        UpdateBtnStatus();
    }
}

All suggestions are welcome.

winforms – Undo/Redo Functionality in DataGridView c#

Review

Welcome to Code Review. There are few suggestions as below.

Layout and formatting

Not sure why many newlines between the curly brackets and the method definition, if statements and for statements. For improving readability, those unnecessary newlines can be removed.

Magic numbers and List<DataTable>

I have no idea about why the initial value of counterUndo is set to 2 (in int counterUndo = 2) and why the inequality check if (_counterUndo != 2) is needed in doWhenClickedUndo method. Is the times of undo operation limited in 2? How about the case of more steps the user wants to undo? To solve this issue, I tried to use Stack<DataTable> instead of List<DataTable> so that the Push, Pop and First methods is available (Stack is useful for maintaining the historical sequence like the states of DataTable here). The following code is as an example implementation with Stack class.

public partial class Form1 : Form
{
    Stack<DataTable> dtStack = new Stack<DataTable>();
    int RecordIndex = 0;
    bool UndoRedo = false;

    public Form1()
    {
        InitializeComponent();

        //    Construct Columns
        dataGridView1.ColumnCount = 1;
        dataGridView1.Columns(0).Name = "0";

        dataGridView1.Rows.Add(20);// Add row

        dtStack.Clear();

        dtStack.Push(GetDataTableFromDGV(dataGridView1));
        UpdateBtnStatus();
    }

    public DataTable GetDataTableFromDGV(DataGridView dgv)
    {
        var dt = new DataTable();

        foreach (DataGridViewColumn column in dgv.Columns)
        {
            dt.Columns.Add(column.Name);
        }

        object() cellValues = new object(dgv.Columns.Count);

        foreach (DataGridViewRow row in dgv.Rows)
        {
            for (int i = 0; i < row.Cells.Count; i++)
            {
                cellValues(i) = row.Cells(i).Value;
            }
            dt.Rows.Add(cellValues);
        }
        return dt;
    }
    
    public void datatablaToDataGrid(DataGridView dgv, DataTable datatable)
    {
        for (int i = 0; i < datatable.Rows.Count; i++)
        {
            for (int j = 0; j < datatable.Columns.Count; j++)
            {
                dgv.Rows(i).Cells(j).Value = datatable.Rows(i)(j).ToString();
            }
        }
    }

    private void UpdateBtnStatus()
    {
        if (RecordIndex == this.dtStack.Count - 1)
            this.btn_Undo.Enabled = false;
        else
            this.btn_Undo.Enabled = true;

        if (RecordIndex == 0)
            this.btn_redo.Enabled = false;
        else
            this.btn_redo.Enabled = true;
    }

    private void btn_Undo_Click(object sender, EventArgs e)
    {
        UndoRedo = true;
        datatablaToDataGrid(dataGridView1, dtStack.ToList()(++RecordIndex));
        UpdateBtnStatus();
        UndoRedo = false;
    }

    private void btn_redo_Click(object sender, EventArgs e)
    {
        UndoRedo = true;
        datatablaToDataGrid(dataGridView1, dtStack.ToList()(--RecordIndex));
        UpdateBtnStatus();
        UndoRedo = false;
    }

    private void dataGridView1_CellValidated(object sender, DataGridViewCellEventArgs e)
    {
        if (UndoRedo)
            return;

        while (RecordIndex != 0)
        {
            dtStack.Pop();
            RecordIndex--;
        }

        DataGridView dgv = (DataGridView)sender;
        int r = e.RowIndex;
        int c = e.ColumnIndex;
        if (dgv.Rows(r).Cells(c).Value != null)
        {
            string dgvResult = dgv.Rows(r).Cells(c).Value.ToString();
            string dtResult = dtStack.First().Rows(r)(c).ToString();
            if (dgvResult != dtResult)
            {
                dtStack.Push(GetDataTableFromDGV(dataGridView1));
            }
        }
        UpdateBtnStatus();
    }
}

windows forms – Como remover mas de una fila de un DataGridView, C#

La situación es la siguiente, necesito que el usuario al seleccionar con el mouse más de una fila en el DataGridView pueda eliminarlas al presionar el botón eliminar, actualmente solo se hacerlo para una eliminar una fila.

ejemplo

static int seleccionFila;

    private void ButtonInformacion_Click(object sender, EventArgs e)
    {
        //Esto es solo un ejemplo, para cargar el datagridview.
        dataGridViewItem.Rows.Add("A001", "Impresora", "80.00");
        dataGridViewItem.Rows.Add("B003", "Abanico", "250.00");
        dataGridViewItem.Rows.Add("A045", "Lanta", "167.00");
        dataGridViewItem.Rows.Add("T010", "Lampara", "45.00");
        dataGridViewItem.Rows.Add("R071", "Mesa", "450.00");

    }

    private void dataGridViewItem_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        seleccionFila = e.RowIndex;
    }

    private void ButtonEliminar_Click(object sender, EventArgs e)
    {
        if (seleccionFila > 0)
            dataGridViewItem.Rows.RemoveAt(seleccionFila);
    }

Como preencher os campos do meu Form clicando numa célula do meu DataGridView?

Eu tô fazendo um programa para registrar todos os membros da minha igreja, pra gente não ficar tendo que guardar vários papéis. Falta pouca coisa pra acabar. Preciso que o meu frmVisualizar_Cadastros seja aberto quando eu clicar em alguma linha do meu DataGridView, que está inserido no frmPrincipal(já tenho um ToolStripMenu funcionando para abrir o frmVisualizar_Cadastros).
Quando clico em qualquer linha do DataGridView, ele até abre o formulário de visualização mas dá mensagem de erro e, assim, não preenche nada. O que tem de errado? Segue o código:

frmVisualizar_Cadastros frmVisualizar_Cadastros1 = new frmVisualizar_Cadastros();
frmVisualizar_Cadastros1.Show();

            DataTable dt = new DataTable();
            string strConn = @"Server = .sqlexpress;Database = bdigreja; Integrated Security = SSPI;";
            SqlConnection conn = new SqlConnection(strConn);
            string membro;
            membro = dataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString();
            SqlDataAdapter da = new SqlDataAdapter("Select nome from tb_crentes where nome = " + membro, conn);
            da.Fill(dt);

            frmVisualizar_Cadastros1.txtNome3.Text = dt.Rows(0)("nome").ToString();

c# – How can I fix my implementation of the ComboBox method of returning second-level properties in DataGridView

As I understand it, ComboBox columns are more dynamic for binding in DataGridView than standard columns, and this flexibility can be used to use DisplayMembers from second-order properties. This approach is the first mentioned here by Mr. Aghaei.

However, I’m not getting it right. My application still throws the exception that “Name” doesn’t exist.

 public void CreateEmployeeTable()
        {

            DataGridViewComboBoxColumn jobTitleColumn = new DataGridViewComboBoxColumn();
            jobTitleColumn.HeaderText = "Job Title";
            jobTitleColumn.DataPropertyName = "JobTitle";
            jobTitleColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
            jobTitleColumn.DataPropertyName = "ID";
            jobTitleColumn.DataSource = globalEmployeeList;
            jobTitleColumn.ValueMember = "ID";
            jobTitleColumn.DisplayMember = "Name";
            jobTitleColumn.ReadOnly = true;

            employeeGridView.AutoGenerateColumns = false;
            employeeGridView.ColumnCount = 2;
            employeeGridView.Columns(0).HeaderText = "Employee ID";
            employeeGridView.Columns(0).DisplayIndex = 0;
            employeeGridView.Columns(0).DataPropertyName = "ID";
            employeeGridView.Columns(1).HeaderText = "Name";
            employeeGridView.Columns(1).DataPropertyName = "ListView";
            employeeGridView.Columns(1).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            employeeGridView.Columns.Add(jobTitleColumn);
            
            employeeGridView.DataSource = globalEmployeeList;                                                                               
        }

Here is the class definition:

     
    public class EmployeeModel
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public string Nickname { get; set; }
        public DepartmentModel Department { get; set; }
        public TitleModel JobTitle { get; set; }
        public DateTime HireDate { get; set; }
        public List<EmailModel> EmailList { get; set; } = new List<EmailModel>();
        public List<PhoneModel> PhoneList { get; set; } = new List<PhoneModel>();
        public List<RestrictionModel> RestrictionsList { get; set; } = new List<RestrictionModel>();
        public List<CitationModel> CitationsList { get; set; } = new List<CitationModel>();
        public List<CertificationModel> CertificationList { get; set; } = new List<CertificationModel>();

        public string ListView
        {
            get
            {
                return $"{LastName}, {FirstName}";
            }
        }

        public string ToEmailString()
        {
            IEnumerable<string> employeeEmailStrings = EmailList.Select(emmod => emmod.ToString());
            string employeeEmailString = string.Join($"{Environment.NewLine}", employeeEmailStrings);

            IEnumerable<string> certificationStrings = CertificationList.Select(clistmod => clistmod.ToString());
            string certificationString = string.Join($"{Environment.NewLine}", certificationStrings);

            IEnumerable<string> phoneStrings = PhoneList.Select(plistmod => plistmod.ToString());
            string phoneString = string.Join($"{Environment.NewLine}", phoneStrings);

            return $"{FirstName}, {LastName}: {Environment.NewLine} -{JobTitle.Name}- {Environment.NewLine} {employeeEmailString} {Environment.NewLine} {certificationString} {Environment.NewLine} {phoneString}";
        }



        public class EmailModel
        {
            public int ID { get; set; }
            public string Address { get; set; }
            public string Type { get; set; }

            public override string ToString()
            {
                return $"{Address} ({Type})";
            }
        }

        public class PhoneModel
        {
            public int ID { get; set; }
            public string Number { get; set; }
            public string Type { get; set; }
            public override string ToString()
            {
                return $"{Number} ({Type})";
            }

        }
    }

And the definition for TitleModel:

    public class TitleModel
    {
        public string Name { get; set; }
        public int ID { get; set; }  

    }
}

como Insertar datos de archivo CSV a DataGridView con Drag Drop en C#?

Tengo un archivo CSV , quiero arrastrarlo a un DataGridView y que se inserten los datos, ya tengo los eventos generados y la propiedad “allow to drop” activada, pero solo logro recuperar la direccion del archivo de esta forma: introducir la descripción de la imagen aquí

Los eventos los tengo configurados de esta manera:

        private void dataGridView1_DragEnter(object sender, DragEventArgs e)
    {
        //Revisa si el formato de los datos del archivo puede ser aceptado
        if (e.Data.GetDataPresent(DataFormats.FileDrop))
        {

            e.Effect = DragDropEffects.Move;
        }
        else
        {

            e.Effect = DragDropEffects.None;
        }
    }

y el siguiente para el drop

private void dataGridView1_DragDrop(object sender, DragEventArgs e)
    {

        if (e.Data.GetDataPresent(DataFormats.FileDrop))
        {

            string() fileList = (string())e.Data.GetData(DataFormats.FileDrop); 
            
            if ((e.Effect == DragDropEffects.Move))
            {
                string() s = (string())e.Data.GetData(DataFormats.FileDrop, false);
                int i;
                for (i = 0; i < s.Length; i++)
                    dataGridView1.Rows.Add(s(i));

            }

        }
    }

Pero solo obtengo el resultado mostrado arriba y no encuentro como leer la informacion dentro del archivo

Como convertir valor de celda de datagridview en c#

Estoy haciendo una pequeño programa, pero necesito cambiar el tipo de dato que hay en la celda del datagridview.

DataSet ds = new DataSet("Percepciones");
                    DataTable dt = new DataTable("Percepciones");

                    dt.Columns.Add("Concepto");
                    dt.Columns.Add("Monto", typeof(Double));
                    dt.Columns.Add("Empleado", typeof(Int32));
     foreach (DataGridViewRow row in DgvNomina.Rows)
                    {
                        if(row.Cells("Sueldo").Value.ToString() != string.Empty)
                        {
                            DataRow r = dt.NewRow();
                            r("Concepto") = "Sueldo Neto";
                            r("Monto") = Convert.ToDouble(row.Cells("Sueldo").Value);//aqui me muestra el error
                            r("Empleado") = row.Cells("ID").Value;
                            dt.Rows.Add(r);
                        }
                    }

                    ds.Tables.Add(dt);

El datagridview lo recorro, y le pongo que el valor de la columna “Sueldo” me lo cambie a tipo Double, en el datagrid lo muestro con formato moneda, ya he intentado, convertirlo pero me sigue mostrando el siguiente error.

System.FormatException: ‘La cadena de entrada no tiene el formato correcto.’

c# – Refresco de dataGridView incorrecto con funciones asincronas

a ver si soy capaz de explicarme.
Tengo un formulario con dos dataGridView, uno muestra un listado de artículos almacenados en una BBDD SQL Server (dgvS200),
el otro muestra uno con artículos que recupero mediante una llamada a una API de una tienda Online(dgvWC)
La finalidad es traspasar los artículos que están en dgvS200 al dgvWC si no están en él.
También tengo un botón para eliminar los artículos seleccionados del dgvWC, todo esto funciona correctamente,
el problema es que después de realizar cada una de estas acciones, llamo una función que me refresca los dataGridView,
pero no se realizan como deberían.
Si llamo esta función fuera de los métodos de inserción y eliminación, funciona bien, pero si la llamada la hacen estos no.
Imagino que el problema está en las llamadas asíncronas que realizo a la API de la tienda, pero ya no sé que más probar.
Os adjunto código por si me podéis echar una mano.

public partial class frmArticles : Form
{
    Cconnexio Ccon = new Cconnexio();
    DataTable articlesS200 = new DataTable();
    DataTable articlesWC = new DataTable();
    List<Cproduct200> p200AInsertar = new List<Cproduct200>();
    List<string> gFiltrats = null;

    public frmArticles()
    {
        InitializeComponent();
    }

    private async void frmArticles_Load(object sender, EventArgs e)
    {
        if (Ccon.lcOk) //Comprueba que la connexion con la API sea correcta
        {
            RefreshGridS200(dgvS200,dgvWC);
        }
        else 
        {
            MessageBox.Show("No se han podido recuperar los datos del servidor");
        }
        gFiltrats = await EquivalArticles(); //me retorna los articulos que estan en la Base de datos pero no en la tienda.
        if(gFiltrats.Count >0)
        Funcions.PintaDgv(gFiltrats, dgvS200, "_codi"); //los pinta en el dataGridView
    }
    private async void RefreshGridS200(DataGridView dgs200, DataGridView dgsWC)
    {
        List<Product> lArticlesWC = Funcions.ObtePrductes();
        List<Cproduct200> lArticles200 = Task.Run(()=> Funcions.S200ToProducte(parametresConnexio, " WHERE PublicarInternet = 2 ")).Result;
        dgs200.DataSource = lArticles200;
        dgsWC.DataSource = lArticlesWC;
    }
    private async Task<List<string>> EquivalArticles()
    {
        List<Product> lArticlesWC =  Funcions.ObtePrductes();
        List<Cproduct200> lArticles200 = await Funcions.S200ToProducte(parametresConnexio, " WHERE PublicarInternet = 2 ");
        List<Cproduct200>articlesFlitrats = lArticles200.Where(x => !lArticlesWC.Select(y => y.sku.Trim()).Contains(x._codi.Trim())).ToList();
        List<string> sFiltrats = articlesFlitrats.Select(x => x._codi).ToList();
        p200AInsertar = articlesFlitrats;
        return sFiltrats;
    }
        private void btDelete_Click(object sender, EventArgs e)
    {
        List<Product> seleccionats = new List<Product>();
        List<string> codis = new List<string>();
        string Lid = "";
        foreach(DataGridViewRow selRow in dgvWC.SelectedRows)
        {
            codis.Add(selRow.Cells("id").Value.ToString());
        }
        Dictionary<string,string>parametres = new Dictionary<string, string>()
        {
            { "include",ListToIn(codis)}
        };
        seleccionats = Task.Run(() => Ccon.ObjecteWC.Product.GetAll(parametres)).Result;
        //Seleccionats contiene los articulos seleccionados del datagrid i se los paso a la funcion BorraProduct
        Funcions.BorraProduct(seleccionats);
        RefreshGridS200(dgvS200, dgvWC);
    }
    private string ListToIn(List<string> containter)
    {
        string cIn = string.Join(",", containter.Select(x => string.Format("{0}", x)));
        return cIn;
    }
    //Esta es la funcion que uso para eliminar los productos seleccionados
    //recibo el List de articulos, paso los id de estos a un List de enteros
    //que es lo que me pide el objeto de la libreria WCObject.Prduct para eliminar los productos
    //Esa excepcion que ignoro es por un bug detectado en la libreria que se solucionará en la próxima version,
    //el proceso de eliminacion se realiza correctamente.
    public void BorraProduct(List<Product> productes)
    {
        List<int> lIdDelete = new List<int>();
        lIdDelete = productes.Select(x => (int)x.id).ToList();
        ProductBatch pb = new ProductBatch();
            pb.delete = lIdDelete;
            try
            {
                var c =  conn.ObjecteWC.Product.UpdateRange(pb);
            }
            catch (Exception e)
            {}
    }
}

Creo que me estoy liando bastante con las llamadas asíncronas, pero no domino demasiado el tema (por no decir nada).

c# – Actualizar datagridview luego de un insert

Estoy intentando actualizar un DataGridView cuando se realiza un insert pero no me ha salido.

Clase Conexión:

//método para cargar el datagridview
        public DataTable Query()
        {
            DataTable datos = new DataTable();//creamos un DataTable
            using(SqlConnection con = new SqlConnection(conn))
            {
                try
                {
                    con.Open();//abrimos la conexión
                    datos.AcceptChanges();
                    String consulta = "SELECT nombre FROM Clientes";//creamos un string con la consulta a sql
                    SqlCommand sqlCommand = new SqlCommand(consulta, con);//cremaos un comando al cual le pasamos las variables que serían la consulta y la conexión para que las ejecute
                    SqlDataAdapter da = new SqlDataAdapter(sqlCommand);//este se encarga de inicializar el command
                    da.Fill(datos);//aquí se agergan o actualizan las fila
                    con.Close();//cerramos al conexión
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            return datos;
        }

En el Form1.cs:

private void Form1_Load(object sender, EventArgs e)
        {
            //Es aquí donde vamos a cargar el dtg
            //creamos bien hermoso el dataset
            ds = new DataSet();

            //acá agregamos la carga de la consulta al dtg
            ds.Tables.Add(conexionSQL.Query());

            //establecemos el origen de los datos
            dtgClientes.DataSource = ds.Tables(0);

        }

Y en el botón donde inserto el registro hago esto:

private void btnInsertar_Click(object sender, EventArgs e)
        {
            Persona p = new Persona();
            ConexionSQL sql = new ConexionSQL();
            string nombre = txtNombre.Text;
            string apellido = txtApellido.Text;
            string mail = txtEmail.Text;
            long tel = Convert.ToInt64(txtTelefono.Text);
            bool idBorrado = false;

            p = new Persona(nombre, apellido, mail, tel, idBorrado);

            sql.insert(p);

            dtgClientes.Update();
            dtgClientes.Refresh();
        }

Pero, no se actualiza el DataGridView luego del insert, ¿Alguna posible solución? Aclaro que los textbox-botón-datagridview están en el mismo Form