This documentation is archived and is not being maintained.

Walkthrough: Creating an Unbound Windows Forms DataGridView Control

You may frequently want to display tabular data that does not originate from a database. For example, you may want to show the contents of a two-dimensional array of strings. The DataGridView class provides an easy and highly customizable way to display data without binding to a data source. This walkthrough shows how to populate a DataGridView control and manage the addition and deletion of rows in "unbound" mode. By default, the user can add new rows. To prevent row addition, set the AllowUserToAddRows property is false.

To copy the code in this topic as a single listing, see How to: Create an Unbound Windows Forms DataGridView Control.

To use an unbound DataGridView control

  1. Create a class that derives from Form and contains the following variable declarations and Main method.

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    public class Form1 : System.Windows.Forms.Form
        private Panel buttonPanel = new Panel();
        private DataGridView songsDataGridView = new DataGridView();
        private Button addNewRowButton = new Button();
        private Button deleteRowButton = new Button();
        static void Main()
            Application.Run(new Form1());
  2. Implement a SetupLayout method in your form's class definition to set up the form's layout.

    private void SetupLayout()
        this.Size = new Size(600, 500);
        addNewRowButton.Text = "Add Row";
        addNewRowButton.Location = new Point(10, 10);
        addNewRowButton.Click += new EventHandler(addNewRowButton_Click);
        deleteRowButton.Text = "Delete Row";
        deleteRowButton.Location = new Point(100, 10);
        deleteRowButton.Click += new EventHandler(deleteRowButton_Click);
        buttonPanel.Height = 50;
        buttonPanel.Dock = DockStyle.Bottom;
  3. Create a SetupDataGridView method to set up the DataGridView columns and properties.

    This method first adds the DataGridView control to the form's Controls collection. Next, the number of columns to be displayed is set using the ColumnCount property. The default style for the column headers is set by setting the BackColor, Forecolor, and Font properties of the DataGridViewCellStyle returned by the ColumnHeadersDefaultCellStyle property.

    Layout and appearance properties are set, and then the column names are assigned. When this method exits, the DataGridView control is ready to be populated.

    private void SetupDataGridView()
        songsDataGridView.ColumnCount = 5;
        songsDataGridView.ColumnHeadersDefaultCellStyle.BackColor = Color.Navy;
        songsDataGridView.ColumnHeadersDefaultCellStyle.ForeColor = Color.White;
        songsDataGridView.ColumnHeadersDefaultCellStyle.Font =
            new Font(songsDataGridView.Font, FontStyle.Bold);
        songsDataGridView.Name = "songsDataGridView";
        songsDataGridView.Location = new Point(8, 8);
        songsDataGridView.Size = new Size(500, 250);
        songsDataGridView.AutoSizeRowsMode =
        songsDataGridView.ColumnHeadersBorderStyle =
        songsDataGridView.CellBorderStyle = DataGridViewCellBorderStyle.Single;
        songsDataGridView.GridColor = Color.Black;
        songsDataGridView.RowHeadersVisible = false;
        songsDataGridView.Columns[0].Name = "Release Date";
        songsDataGridView.Columns[1].Name = "Track";
        songsDataGridView.Columns[2].Name = "Title";
        songsDataGridView.Columns[3].Name = "Artist";
        songsDataGridView.Columns[4].Name = "Album";
        songsDataGridView.Columns[4].DefaultCellStyle.Font =
            new Font(songsDataGridView.DefaultCellStyle.Font, FontStyle.Italic);
        songsDataGridView.SelectionMode =
        songsDataGridView.MultiSelect = false;
        songsDataGridView.Dock = DockStyle.Fill;
        songsDataGridView.CellFormatting += new
  4. Create a PopulateDataGridView method to add rows to the DataGridView control.

    Each row represents a song and its associated information.

    private void PopulateDataGridView()
        string[] row0 = { "11/22/1968", "29", "Revolution 9", 
            "Beatles", "The Beatles [White Album]" };
        string[] row1 = { "1960", "6", "Fools Rush In", 
            "Frank Sinatra", "Nice 'N' Easy" };
        string[] row2 = { "11/11/1971", "1", "One of These Days", 
            "Pink Floyd", "Meddle" };
        string[] row3 = { "1988", "7", "Where Is My Mind?", 
            "Pixies", "Surfer Rosa" };
        string[] row4 = { "5/1981", "9", "Can't Find My Mind", 
            "Cramps", "Psychedelic Jungle" };
        string[] row5 = { "6/10/2003", "13", 
            "Scatterbrain. (As Dead As Leaves.)", 
            "Radiohead", "Hail to the Thief" };
        string[] row6 = { "6/30/1992", "3", "Dress", "P J Harvey", "Dry" };
        songsDataGridView.Columns[0].DisplayIndex = 3;
        songsDataGridView.Columns[1].DisplayIndex = 4;
        songsDataGridView.Columns[2].DisplayIndex = 0;
        songsDataGridView.Columns[3].DisplayIndex = 1;
        songsDataGridView.Columns[4].DisplayIndex = 2;
  5. With the utility methods in place, you can attach event handlers.

    You will handle the Add and Delete buttons' Click events, the form's Load event, and the DataGridView control's CellFormatting event.

    When the Add button's Click event is raised, a new, empty row is added to the DataGridView.

    When the Delete button's Click event is raised, the selected row is deleted, unless it is the row for new records, which enables the user add new rows. This row is always the last row in the DataGridView control.

    When the form's Load event is raised, the SetupLayout, SetupDataGridView, and PopulateDataGridView utility methods are called.

    When the CellFormatting event is raised, each cell in the Date column is formatted as a long date, unless the cell's value cannot be parsed.

    public Form1()
        this.Load += new EventHandler(Form1_Load);
    private void Form1_Load(System.Object sender, System.EventArgs e)
    private void songsDataGridView_CellFormatting(object sender,
        System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
        if (this.songsDataGridView.Columns[e.ColumnIndex].Name == "Release Date")
            if (e != null)
                if (e.Value != null)
                        e.Value = DateTime.Parse(e.Value.ToString())
                        e.FormattingApplied = true;
                    catch (FormatException)
                        Console.WriteLine("{0} is not a valid date.", e.Value.ToString());
    private void addNewRowButton_Click(object sender, EventArgs e)
    private void deleteRowButton_Click(object sender, EventArgs e)
        if (this.songsDataGridView.SelectedRows.Count > 0 &&
            this.songsDataGridView.SelectedRows[0].Index !=
            this.songsDataGridView.Rows.Count - 1)

You can now test the form to make sure it behaves as expected.

To test the form

  • Press F5 to run the application.

    You will see a DataGridView control that displays the songs listed in PopulateDataGridView. You can add new rows with the Add Row button, and you can delete selected rows with the Delete Row button. The unbound DataGridView control is the data store, and its data is independent of any external source, such as a DataSet or an array.

This application gives you a basic understanding of the DataGridView control's capabilities. You can customize the appearance and behavior of the DataGridView control in several ways: