We help IT Professionals succeed at work.

creating a column update button for a dataGridView in C#

Hi,

With the help of experts on this zone I was able to create a delete column button for a dataGridView, which uses the following code to deleted the clicked row:


 private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            this.dataGridView1.Rows.RemoveAt(e.RowIndex);
        }

My question is: would I be able to create a similar update column button that would update whatever changes in any of the cells in the clicked row...? If so, could you show me how...?

Thanks
Comment
Watch Question

Commented:
You can just point to the row in the datagridview and modify the value. Something like below:-

' Modify the value in the first cell of the second row.
Me.dataGridView1.Rows[1].Cells[0].Value = "new value"

' The previous line is equivalent to the following line.
Me.dataGridView1[0, 1].Value = "new value"

Reference:-http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.rows.aspx
Vel EousResearch & Development Manager

Commented:
Depending on how you are binding your data to your datagridview you could use the INotifyPropertChanged event handler to Detect alterations to your source.

Take a look at the code snippet below which provides an example of such functionality.  There is a DataGridView that has a DataSource of a BindingList<T>.  You can manually update the DataSource by directly editing a row in the DataGridView or use one of the buttons at the bottom of the form to add a new object to the DataSource or alter an existing object.  There is also a button which prints the content of the BindingList<T> to a TextBox control just so you can see that your changes are being made.

I've provided the Form1.cs and Form1.Designer.cs code for completeness.
// Form1.Designer.cs

namespace EE.WinForms
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this._dgProcessors = new System.Windows.Forms.DataGridView();
            this._btnAddNewCpu = new System.Windows.Forms.Button();
            this._btnAlterExistingCpu = new System.Windows.Forms.Button();
            this._txtCollectionOutput = new System.Windows.Forms.TextBox();
            this._btnPrintCollection = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this._dgProcessors)).BeginInit();
            this.SuspendLayout();
            // 
            // _dgProcessors
            // 
            this._dgProcessors.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this._dgProcessors.Location = new System.Drawing.Point(12, 12);
            this._dgProcessors.Name = "_dgProcessors";
            this._dgProcessors.Size = new System.Drawing.Size(524, 223);
            this._dgProcessors.TabIndex = 0;
            // 
            // _btnAddNewCpu
            // 
            this._btnAddNewCpu.Location = new System.Drawing.Point(12, 377);
            this._btnAddNewCpu.Name = "_btnAddNewCpu";
            this._btnAddNewCpu.Size = new System.Drawing.Size(150, 23);
            this._btnAddNewCpu.TabIndex = 1;
            this._btnAddNewCpu.Text = "Add New CPU";
            this._btnAddNewCpu.UseVisualStyleBackColor = true;
            this._btnAddNewCpu.Click += new System.EventHandler(this._btnAddNewCpu_Click);
            // 
            // _btnAlterExistingCpu
            // 
            this._btnAlterExistingCpu.Location = new System.Drawing.Point(197, 377);
            this._btnAlterExistingCpu.Name = "_btnAlterExistingCpu";
            this._btnAlterExistingCpu.Size = new System.Drawing.Size(150, 23);
            this._btnAlterExistingCpu.TabIndex = 2;
            this._btnAlterExistingCpu.Text = "Alter Existing CPU";
            this._btnAlterExistingCpu.UseVisualStyleBackColor = true;
            this._btnAlterExistingCpu.Click += new System.EventHandler(this._btnAlterExistingCpu_Click);
            // 
            // _txtCollectionOutput
            // 
            this._txtCollectionOutput.Location = new System.Drawing.Point(12, 241);
            this._txtCollectionOutput.Multiline = true;
            this._txtCollectionOutput.Name = "_txtCollectionOutput";
            this._txtCollectionOutput.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this._txtCollectionOutput.Size = new System.Drawing.Size(524, 130);
            this._txtCollectionOutput.TabIndex = 3;
            // 
            // _btnPrintCollection
            // 
            this._btnPrintCollection.Location = new System.Drawing.Point(386, 377);
            this._btnPrintCollection.Name = "_btnPrintCollection";
            this._btnPrintCollection.Size = new System.Drawing.Size(150, 23);
            this._btnPrintCollection.TabIndex = 4;
            this._btnPrintCollection.Text = "Print Collection";
            this._btnPrintCollection.UseVisualStyleBackColor = true;
            this._btnPrintCollection.Click += new System.EventHandler(this._btnPrintCollection_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(548, 412);
            this.Controls.Add(this._btnPrintCollection);
            this.Controls.Add(this._txtCollectionOutput);
            this.Controls.Add(this._btnAlterExistingCpu);
            this.Controls.Add(this._btnAddNewCpu);
            this.Controls.Add(this._dgProcessors);
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this._dgProcessors)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.DataGridView _dgProcessors;
        private System.Windows.Forms.Button _btnAddNewCpu;
        private System.Windows.Forms.Button _btnAlterExistingCpu;
        private System.Windows.Forms.TextBox _txtCollectionOutput;
        private System.Windows.Forms.Button _btnPrintCollection;

    }
}



// Form1.cs

using System;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;

namespace EE.WinForms
{
    public partial class Form1 : Form
    {
        // BindingList<T> supports object notification unlike other generic collections
        // this is collection will automatically react to updates
        public BindingList<Processor> processors = new BindingList<Processor>();

        public Form1()
        {
            InitializeComponent();
            
            // disable automatic column generation as we'll do this ourselves
            this._dgProcessors.AutoGenerateColumns = false;
            // declare and instantiate a new data grid column
            DataGridViewTextBoxColumn makeColumn = new DataGridViewTextBoxColumn();
            // give it an identity
            makeColumn.DataPropertyName = "Make";
            makeColumn.HeaderText = "Make";
            // repeated as above for model property
            DataGridViewTextBoxColumn modelColumn = new DataGridViewTextBoxColumn();
            modelColumn.DataPropertyName = "Model";
            modelColumn.HeaderText = "Model";
            // repeated as above for year property
            DataGridViewTextBoxColumn yearColumn = new DataGridViewTextBoxColumn();
            yearColumn.DataPropertyName = "Year";
            yearColumn.HeaderText = "Year";
            // add the columns to the data grid
            this._dgProcessors.Columns.Add(makeColumn);
            this._dgProcessors.Columns.Add(modelColumn);
            this._dgProcessors.Columns.Add(yearColumn);

            // add some processors to the collection
            this.PopulateProcessors();
            // bind the collection to the data grid
            this._dgProcessors.DataSource = processors;
        }

        // populates the processor collection with some content
        private void PopulateProcessors()
        {
            processors.Add(new Processor("Intel", "i7 9xx", "2008"));
            processors.Add(new Processor("AMD", "Opteron 240", "2003"));
            processors.Add(new Processor("Cyrix", "6x86", "1996"));
        }

        // adds another new cpu to the processor collection
        private void _btnAddNewCpu_Click(object sender, System.EventArgs e)
        {
            this.processors.Add(new Processor("ARM", "A15", "TBC"));
        }

        // alters an existing processor in the collection
        private void _btnAlterExistingCpu_Click(object sender, System.EventArgs e)
        {
            this.processors[1].Year = "Unkown";
        }

        // print the collection content to the text field so you can see what is contained is what is displayed in the data grid
        private void _btnPrintCollection_Click(object sender, System.EventArgs e)
        {
            this._txtCollectionOutput.AppendText("-------------------------------------------" + Environment.NewLine);
            foreach (Processor cpu in this.processors)
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append(string.Format("Make: {0}, ", cpu.Make));
                stringBuilder.Append(string.Format("Model: {0}, ", cpu.Model));
                stringBuilder.Append(string.Format("Year: {0}", cpu.Year));
                this._txtCollectionOutput.AppendText(stringBuilder.ToString() + Environment.NewLine);
            }
            this._txtCollectionOutput.AppendText("-------------------------------------------" + Environment.NewLine);
        }
    }

    // the processor class that implements the INotifyPropertyChanged interface
    public class Processor : INotifyPropertyChanged
    {
        // some properties about the processor
        private string _make;
        private string _model;
        private string _year;

        // the property changed event handler
        public event PropertyChangedEventHandler PropertyChanged;

        // constructor
        public Processor(string make, string model, string year)
        {
            this._make = make;
            this._model = model;
            this._year = year;
        }

        // make field
        public string Make
        {
            get
            {
                return this._make;
            }
            set
            {
                this._make = value; 
                this.NotifyPropertyChanged("Make");
            } 
        }

        // model field
        public string Model
        {
            get
            {
                return this._model; 
            } 
            set 
            { 
                this._model = value; 
                this.NotifyPropertyChanged("Model"); 
            } 
        }

        // year field
        public string Year
        {
            get
            {
                return this._year;
            }
            set
            {
                this._year = value;
                this.NotifyPropertyChanged("Year");
            } 
        }

        // property changed event handler
        // this is fired whenever a property of the instance is changed
        private void NotifyPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }
}

Open in new window

Author

Commented:
@TempDBA:

Thanks,
your example is very clear. The only thing missing is a way to identify the cell (and consequently the row) which the user edited.... I should have explained in my question that my dataGridView1 is unbound, I use the code below to fetch the data from a table in an Sql database.

I suppose if I find a way to know how to identify the cell and row the user edited  I would then use my own method to save the edited data in the table...
private void getDataForGrid()
        {
                    
            SqlConnection con;
            con = new SqlConnection("Server=PC;Database=HelpDesk;integrated security=True");
            SqlCommand CmdSelect = new SqlCommand("select dDate as Date, tTime as Time,Name,Test,Phone from Appointments where dDate=@dDate", con);
            CmdSelect.Parameters.Add("dDate", SqlDbType.Date, 10, "dDate").Value = dt;
            SqlDataAdapter dataAdapter1 = new SqlDataAdapter(CmdSelect);
            DataSet ds = new DataSet();
            dataAdapter1.Fill(ds, "Appointments");
            dataGridView1.DataSource = null;
            dataGridView1.Rows.Clear();
            dataGridView1.DataSource = ds.Tables["Appointments"];

Open in new window

Author

Commented:
TempDBA:

Thank you, I didn't realize the link you referred me to had all this information.... thanks.

Author

Commented:
very good

Commented:
You are most welcome.