0% found this document useful (0 votes)
295 views

Windows Forms Data Controls and Data Binding FAQ

Windows Forms Data Controls and Databinding FAQ tries to capture the high-level features with some depth in the Windows Forms Data Controls and Binding areas. This material should not be considered as a complete coverage of the frequently asked questions.

Uploaded by

Say San Say
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
295 views

Windows Forms Data Controls and Data Binding FAQ

Windows Forms Data Controls and Databinding FAQ tries to capture the high-level features with some depth in the Windows Forms Data Controls and Binding areas. This material should not be considered as a complete coverage of the frequently asked questions.

Uploaded by

Say San Say
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

Windows Forms Data Controls and Databinding FAQ

  United States (English) Sign in

Home Library Learn Downloads Support Community Forums

Microsoft Developer Network > Forums Home > Windows Forms Forums > Windows Forms Data Need Help with Forums? (FAQ)
Controls and Databinding > Windows Forms Data Controls and Databinding FAQ

Ask a question Search Forums:

Windows Forms Data Controls and Databinding FAQ

Zhi-Xin Ye  

Tuesday, December 04, 2007 3:17 AM

     This material should not be considered as a complete coverage of the frequently
5 asked questions, but it tries to capture the high-level features with some depth in the
Sign In Windows Forms Data Controls and Binding areas.
to Vote

1.  How do I restrict users from setting focus to a specific cell? 


2.  How can I show vertical text in the cell? 
3.  How to change the default Sort Mode ? 
4.  Can I dynamically change the DataGridViewCell type? 
5.  How do I  make the DataGridViewComboBoxColumn show  up as a text box column
when not in edit mode? 
6.  How do I show multi-layered column headers? 
7.  How to make multiple controls in a single cell? 
8.  How to display grouped data in a DataGridView? 
9.  How can I make the Enter key work as Tab key? 
10. How to restrict the input in the text column to be numeric only? 
11. How to make the '\t' character work in the DataGridViewCell when displaying? 
12. How to make the Enter key and Tab key work in DataGridViewTextBoxCell when in
edit mode? 
13. How to make the DataGridView show gridlines in all display areas? 
14. How do I prevent a particular cell from being editable? 
15. How do I disable a cell? 
16. How do I show controls in all cells regardless of edit? 
17. How do I handle the SelectedIndexChanged event? 
18. How do I show icon and text in the same cell? 
19. How do I hide a column? 
20. How do I prevent the user from sorting on a column? 
21. How do I sort on multiple columns? 
22. How do I perform drag and drop reorder of rows?  
23. How do I make the last column wide enough to occupy all the remaining client area
of the grid? 
24. How do I have the cell text wrap? 
25. How do I make the image column not show any images? 
26. How do I enable typing in the combo box cell? 
27. How do I have a combo box column display a sub set of data based upon the value
of a different combo box column? 
28. How do I show the error icon when the user is editing the cell? 
29. How do I show unbound data along with bound data? 
30. How do I show data that comes from two tables? 
31. How do I show master-details? 
32. How do I show master-details in the same DataGridView? 
33. How do I prevent sorting? 
34. How do I commit the data to the database when clicking on a toolstrip button? 
35. How do I display a confirmation dialog when the user tries to delete a row? 

Edited by Bruce.Zhou Wednesday, December 31, 2008 9:11 AM Change bookmark


Edited by Bruce.Zhou Wednesday, December 31, 2008 9:50 AM change bookmark
Edited by Bruce.Zhou Friday, January 02, 2009 7:15 AM change bookmark
Edited by Bruce.Zhou Wednesday, December 31, 2008 9:47 AM change bookmark
Edited by Bruce.Zhou Wednesday, December 31, 2008 9:54 AM change bookmark

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

Edited by Bruce.Zhou Wednesday, December 31, 2008 9:36 AM change bookmark


Edited by Bruce.Zhou Wednesday, December 31, 2008 9:35 AM change bookmark
Edited by Bruce.Zhou Wednesday, December 31, 2008 9:39 AM change bookmark
Edited by Bruce.Zhou Wednesday, December 31, 2008 9:41 AM change bookmark
Edited by Bruce.Zhou Wednesday, December 31, 2008 10:21 AM Change bookmark
Edited by Bruce.Zhou Wednesday, December 31, 2008 9:29 AM change bookmark
 

All Replies
Zhi-Xin Ye  

Tuesday, December 04, 2007 3:21 AM

1.      How do I restrict users from setting focus to a specific cell? 


0 By default the DataGridView's navigation model does not have any ability to restrict
Sign In focus to a specific cell. You can implement your own navigation logic by overriding the
to Vote appropriate keyboard, navigation and mouse methods such as
DataGridView.OnKeyDown, DataGridView.ProcessDataGridViewKey,
DataGridView.SetCurrentCellAddressCore, DataGridView.SetSelectedCellCore,
DataGridView.OnMouseDown.

For example, assume you want to restrict users from setting focus on the second
column, then you have to derive from the DataGridView class and override the
SetCurrentCellAddressCore and SetSelectedCellCore to implement the logic you
want, the following sample demonstrates how to do this.

Code Block
public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
 
            private void Form1_Load(object sender, EventArgs e)
            {
                DataTable dt = new DataTable();
                dt.Columns.Add("c1");
                dt.Columns.Add("c2");
                dt.Columns.Add("c3");
                for (int j = 0; j < 10; j++)
                {
                    dt.Rows.Add("aaa" + j.ToString(), "bbb");
                }
 
                this.myDataGridView1.DataSource = dt;
                this.myDataGridView1.ColumnToSkip = 1;
            }
        }
 
        public class myDataGridView : DataGridView
        {
            private int columnToSkip = -1;
 
            public int ColumnToSkip
            {
                get { return columnToSkip; }
                set { columnToSkip = value; }
            }
 
            protected override bool SetCurrentCellAddressCore(int columnIndex, int rowIndex,
                bool setAnchorCellAddress, bool validateCurrentCell, bool throughMouseClick)
            {
                if (columnIndex == this.columnToSkip && this.columnToSkip != -1)

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

                {
                    if (this.columnToSkip == this.ColumnCount - 1)
                    {
                        return base.SetCurrentCellAddressCore(0, rowIndex + 1,
                            setAnchorCellAddress, validateCurrentCell, throughMouseClick);
                    }
                    else
                    {
                        if (this.ColumnCount != 0)
                        {
                            return base.SetCurrentCellAddressCore(columnIndex + 1, rowIndex,
                                setAnchorCellAddress, validateCurrentCell, throughMouseClick);
                        }
                    }
                }
                return base.SetCurrentCellAddressCore(columnIndex, rowIndex,
                    setAnchorCellAddress, validateCurrentCell, throughMouseClick);
            }
 
            protected override void SetSelectedCellCore(int columnIndex, int rowIndex, bool
selected)
            {
                if (columnIndex == this.columnToSkip)
                {
                    if (this.columnToSkip == this.ColumnCount - 1)
                    {
                        base.SetSelectedCellCore(0, rowIndex + 1, selected);
                    }
                    else
                    {
                        if (this.ColumnCount != 0)
                        {
                            base.SetSelectedCellCore(columnIndex + 1, rowIndex, selected);
                        }
                    }
                }
                else
                {
                    base.SetSelectedCellCore(columnIndex, rowIndex, selected);
                }
            }
        }
 

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?
PostID=316283&SiteID=1

Edited by Bruce.Zhou Wednesday, December 31, 2008 9:09 AM change bookmark


Edited by Bruce.Zhou Wednesday, December 31, 2008 9:12 AM change bookmark
 

Zhi-Xin Ye  

Tuesday, December 04, 2007 3:23 AM

2      How can I show vertical text in the cell?


0 To make text show vertically in the cells, you have to handle the CellPainting event to
Sign In draw the text by yourself with a StringFormatFlags.DirectionVertical flag, the following
to Vote sample demonstrates how to do this:

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

      
Code Block
private void Form1_Load(object sender, EventArgs e)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("c1");
            dt.Columns.Add("c2");
            for (int j = 0; j < 10; j++)
            {
                dt.Rows.Add("aaaaaaaaa", "bbbb");
            }
            this.dataGridView1.DataSource = dt;
 
            for (int j = 0; j < 10; j++)
            {
                int height = TextRenderer.MeasureText(
                    this.dataGridView1[0, j].Value.ToString(),
                    this.dataGridView1.DefaultCellStyle.Font).Width;
                this.dataGridView1.Rows[j].Height = height;
            }
 
            this.dataGridView1.CellPainting += new
                 DataGridViewCellPaintingEventHandler(dataGridView1_CellPainting); ;
        }
 
        void dataGridView1_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
        {
            if (e.ColumnIndex == 0 && e.RowIndex > -1 && e.Value != null)
            {
                e.Paint(e.CellBounds, DataGridViewPaintParts.All
                     & ~DataGridViewPaintParts.ContentForeground);
                StringFormat sf = new StringFormat();
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
                sf.FormatFlags = StringFormatFlags.DirectionVertical;
                e.Graphics.DrawString(e.Value.ToString(), e.CellStyle.Font,
                    new SolidBrush(e.CellStyle.ForeColor), e.CellBounds, sf);
                e.Handled = true;
            }
        }

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2351571&SiteID=1

Zhi-Xin Ye  

Tuesday, December 04, 2007 3:36 AM

3. How to change the default Sort Mode?


0
Sign In The default SortMode is DataGridViewColumnSortMode.Automatic, in some cases
to Vote developers would like to change this  default setting but they dislike looping through
the columns to change this setting, like this guy on this thread
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2302617&SiteID=1

To achieve this, we can derive from the DataGridView class and override its
OnColumnAdded method  to change the default setting, something like this

Code Block

        public
class mydgv : DataGridView
        {
            protected override void OnColumnAdded(DataGridViewColumnEventArgs e)
            {
                base.OnColumnAdded(e);
                e.Column.SortMode = DataGridViewColumnSortMode.NotSortable;
            }
        }

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?
PostID=2302617&SiteID=1

Edited by Bruce.Zhou Wednesday, December 31, 2008 9:14 AM change bookmark


 

Zhi-Xin Ye  

Tuesday, December 04, 2007 3:38 AM

4. Can I dynamically change the DataGridViewCell type?


0 Yes.  For example in this thread http://forums.microsoft.com/MSDN/ShowPost.aspx?
Sign In PostID=1924281&SiteID=1
to Vote the OP would like to change the DataGridViewComboBoxCell to
DataGridViewTextBoxCell dynamically  based on the value selected, in fact,  the cell
type can be changed, just by creating a cell of the type you want and assigning it to
the cell which you want to change, something like this

Code Block

        private void Form1_Load(object sender, EventArgs e)


        {
            DataTable dt = new DataTable("b");
            dt.Columns.Add("col");
            dt.Rows.Add("bb1");
            dt.Rows.Add("bb2");
            dt.Rows.Add("bb3");
 
            this.dataGridView1.DataSource = dt;
 
            DataGridViewComboBoxColumn cmb = new
DataGridViewComboBoxColumn();
            cmb.Items.Add("111");
            cmb.Items.Add("222");
            cmb.Items.Add("333");
            this.dataGridView1.Columns.Add(cmb);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            DataGridViewTextBoxCell cell = new DataGridViewTextBoxCell();
            cell.Value = "bb1";
            this.dataGridView1[1, 1] = cell;
        }

 
Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1924281&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2122903&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1358083&SiteID=1

Zhi-Xin Ye  

Tuesday, December 04, 2007 3:42 AM

5.  How do I  make the DataGridViewComboBoxColumn show  up as a text box


column when not in edit mode?
0
Sign In
to Vote
This is can be done by setting the DataGridViewComboBoxColumn.DisplayStyle
property to DataGridViewComboBoxDisplayStyle.Nothing.

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

Zhi-Xin Ye  

Tuesday, December 04, 2007 3:48 AM

6. How do I show multi-layered column headers?


0  
Sign In
As this thread http://forums.microsoft.com/MSDN/ShowPost.aspx?
to Vote
PostID=1378821&SiteID=1 asked, someone would like to make the DataGridView
column headers show layered information, something like this

---------------------------------------------------------------

                |   January       |   February      |     March       |

        |  Win  | Loss   |  Win   | Loss   |  Win | Loss    |

---------------------------------------------------------------

Team1       |         |          |         |          |          |         |

Team2       |         |          |         |          |          |         |

TeamN       |         |          |         |          |          |         |

---------------------------------------------------------------

To achieve this kind of effect, we should handle the DataGridView.Painting and


DataGridView.CellPainting events to custom draw the header style we want, the
following sample demonstrates how to do this

(see next post)

Zhi-Xin Ye  

Tuesday, December 04, 2007 3:51 AM

Code Block
0
Sign In
to Vote         private void DgvColumnHeaderMerge_Load(object sender, EventArgs e)
        {
            this.dataGridView1.Columns.Add("JanWin", "Win");
            this.dataGridView1.Columns.Add("JanLoss", "Loss");
            this.dataGridView1.Columns.Add("FebWin", "Win");
            this.dataGridView1.Columns.Add("FebLoss", "Loss");
            this.dataGridView1.Columns.Add("MarWin", "Win");
            this.dataGridView1.Columns.Add("MarLoss", "Loss");
 
            for (int j = 0; j < this.dataGridView1.ColumnCount; j++)
            {
                this.dataGridView1.Columns[j].Width = 45;
            }
            this.dataGridView1.ColumnHeadersHeightSizeMode =
                 DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
            this.dataGridView1.ColumnHeadersHeight =
                        this.dataGridView1.ColumnHeadersHeight * 2;
            this.dataGridView1.ColumnHeadersDefaultCellStyle.Alignment =
                 DataGridViewContentAlignment.BottomCenter;
            this.dataGridView1.CellPainting += new
                 DataGridViewCellPaintingEventHandler(dataGridView1_CellPainting);
            this.dataGridView1.Paint += new PaintEventHandler(dataGridView1_Paint);
 

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

        }
 
        void dataGridView1_Paint(object sender, PaintEventArgs e)
        {
            string[] monthes = { "January", "February", "March" };
            for (int j = 0; j < 6; )
            {
                //get the column header cell
                Rectangle r1 = this.dataGridView1.GetCellDisplayRectangle(j, -1, true);
 
                r1.X += 1;
                r1.Y += 1;
                r1.Width = r1.Width * 2 - 2;
                r1.Height = r1.Height / 2 - 2;
                e.Graphics.FillRectangle(new
                   SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.BackColor), r1);
                StringFormat format = new StringFormat();
                format.Alignment = StringAlignment.Center;
                format.LineAlignment = StringAlignment.Center;
                e.Graphics.DrawString(monthes[j / 2],
                    this.dataGridView1.ColumnHeadersDefaultCellStyle.Font,
                    new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor),
                    r1,
                    format);
                j += 2;
            }
        }
 
        void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex == -1 && e.ColumnIndex > -1)
            {
                e.PaintBackground(e.CellBounds, false);
 
                Rectangle r2 = e.CellBounds;
                r2.Y += e.CellBounds.Height / 2;
                r2.Height = e.CellBounds.Height / 2;
                e.PaintContent(r2);
                e.Handled = true;
            }
        }

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1378821&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1442065&SiteID=1

Zhi-Xin Ye Wednesday, December 05, 2007 5:56 AM

7.     How to make multiple controls in a single cell?

0
Sign In As asked in this thread http://forums.microsoft.com/MSDN/ShowPost.aspx?
to Vote PostID=1425662&SiteID=1
the OP would like to make a Button to show up along with the TextBox. This can be
done by creating a UserControl to host the TextBox and Button, add it into the
controls collection of the DataGridView, initially make it invisible, then handle the
CellBeginEdit event to show the UserControl at the current cell. You also have to
handle the Scroll event to adjust the location of the UserControl in case the Scrollbars

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

shows, and handle the CellEndEdit event to change the cell value with the value got
from the UserControl. For a full sample please check the thread.

And there is another similar thread where the OP wants to display a Dropdown text
editor while editing in the cells.
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1506454&SiteID=1

Zhi-Xin Ye Wednesday, December 05, 2007 6:18 AM

8. How to display grouped data in a DataGridView?


0
Sign In          For example, how can I display grouped data as the following graph shows;
to Vote

The key point here is to handle the CellPainting event to custom draw the cell to get
the style you want, a sample code demonstrates how to do this:

Code Block
public class GroupByGrid : DataGridView
        {
 
            protected override void OnCellFormatting(
               DataGridViewCellFormattingEventArgs args)
            {
                // Call home to base
                base.OnCellFormatting(args);
 
                // First row always displays
                if (args.RowIndex == 0)
                    return;
 
 
                if (IsRepeatedCellValue(args.RowIndex, args.ColumnIndex))
                {
                    args.Value = string.Empty;
                    args.FormattingApplied = true;
                }
            }
 
            private bool IsRepeatedCellValue(int rowIndex, int colIndex)
            {
                DataGridViewCell currCell =
                   Rows[rowIndex].Cells[colIndex];
                DataGridViewCell prevCell =
                   Rows[rowIndex - 1].Cells[colIndex];
 
                if ((currCell.Value == prevCell.Value) ||

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

                   (currCell.Value != null && prevCell.Value != null &&


                   currCell.Value.ToString() == prevCell.Value.ToString()))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
 
            protected override void OnCellPainting(
               DataGridViewCellPaintingEventArgs args)
            {
                base.OnCellPainting(args);
 
                args.AdvancedBorderStyle.Bottom =
                   DataGridViewAdvancedCellBorderStyle.None;
 
                // Ignore column and row headers and first row
                if (args.RowIndex < 1 || args.ColumnIndex < 0)
                    return;
 
                if (IsRepeatedCellValue(args.RowIndex, args.ColumnIndex))
                {
                    args.AdvancedBorderStyle.Top =
                       DataGridViewAdvancedCellBorderStyle.None;
                }
                else
                {
                    args.AdvancedBorderStyle.Top = AdvancedCellBorderStyle.Top;
                }
            }
        }

Zhi-Xin Ye Wednesday, December 05, 2007 6:21 AM

9. How can I make the Enter key work as Tab key?

0
Sign In       To make the Enter key work as Tab key, we have to derive from the DataGridView control,
to Vote and there are two cases to think about. One is when the DataGridView is not in edit mode: in
this case, we can override the ProcessDataGridViewKey() method to change the navigation logic
as we want. The other case is when the DataGridView is in edit mode: in this case, the Enter key
is processed in the ProcessDialogKey() method, so we should override this method to write our
own logic. The following sample demonstrates how to do this.

 public class MyDataGridView : DataGridView


    {
        protected override bool ProcessDataGridViewKey(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                this.ProcessTabKey(e.KeyData);
                return true;
            }
            return base.ProcessDataGridViewKey(e);
        }

        protected override bool ProcessDialogKey(Keys keyData)


        {
            if (keyData == Keys.Enter)
            {
                this.ProcessTabKey(keyData);
                return true;
            }
            return base.ProcessDialogKey(keyData);
        }
    }

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1864004&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1437503&SiteID=1

Zhi-Xin Ye Wednesday, December 05, 2007 6:23 AM

10.    How to restrict the input in the text column to be numeric only?

0
Sign In When the textbox cell is in edit mode, the EditingControl is shown in the cell, we can
to Vote restrict the input by handling the TextBox.KeyPress event to filter the keyboard input
through the char.IsDigit() method. The following sample demonstrates how to do this.

Code Block
public partial class DgvNumberOnlyColumn : Form
        {
            public DgvNumberOnlyColumn()
            {
                InitializeComponent();
            }
 
            private void DgvNumberOnlyColumn_Load(object sender, EventArgs e)
            {
                this.dataGridView1.Columns.Add("col1", "col1");
                this.dataGridView1.Columns.Add("col2", "col2");
                this.dataGridView1.Rows.Add();
                this.dataGridView1.EditingControlShowing += new
                     DataGridViewEditingControlShowingEventHandler(
                     dataGridView1_EditingControlShowing);
            }
 
            void dataGridView1_EditingControlShowing(object sender,
                 DataGridViewEditingControlShowingEventArgs e)
            {
                if (this.dataGridView1.CurrentCell.ColumnIndex == 0)
                {
                    if (e.Control is TextBox)
                    {
                        TextBox tb = e.Control as TextBox;
                        tb.KeyPress -= new KeyPressEventHandler(tb_KeyPress);
                        tb.KeyPress += new KeyPressEventHandler(tb_KeyPress);
                    }
                }
            }
 
            void tb_KeyPress(object sender, KeyPressEventArgs e)
            {
                if (!(char.IsDigit(e.KeyChar)))
                {
                    Keys key = (Keys)e.KeyChar;
 
                    if (!(key == Keys.Back || key == Keys.Delete))
                    {
                        e.Handled = true;
                    }
                }
            }
        }

Related threads:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1757999&SiteID=1

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

Zhi-Xin Ye Wednesday, December 05, 2007 6:26 AM

11.    How to make the '\t' character work in the DataGridViewCell when
displaying?
0
Sign In
to Vote When the DataGridView paints the cell value, the '\t' character is ignored by default. To
make the '\t' char work, we can handle the CellPainting event to draw the text by
ourselves.

Code Block

        void dataGridView1_CellPainting(object sender,


DataGridViewCellPaintingEventArgs e)
        {
            e.Paint(e.CellBounds,
                DataGridViewPaintParts.All &
~DataGridViewPaintParts.ContentForeground);
            if (e.Value != null)
            {
                e.Graphics.DrawString(e.Value.ToString(),
                    e.CellStyle.Font,
                    new SolidBrush(e.CellStyle.ForeColor),
                    e.CellBounds.X, e.CellBounds.Y);
            }
            e.Handled = true;
        }

Related threads:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1898048&SiteID=1

Zhi-Xin Ye Wednesday, December 05, 2007 6:31 AM

12.    How to make the Enter key and Tab key work in DataGridViewTextBoxCell
when in edit mode?
0
Sign In To make the Enter key and Tab key work in the cell while editing, you have to derive
to Vote from the DataGridView control, override the ProcessDataGridViewKey method to filter
the Tab and Enter key, something like this:

Code Block

        class zxyDataGridView : DataGridView


        {
            protected override bool ProcessDataGridViewKey(KeyEventArgs e)
            {
                switch (e.KeyCode)
                {
                    case Keys.Tab:
                        return false;
                    case Keys.Enter:
                        {
                            if (this.EditingControl != null)
                            {
                                if (this.EditingControl is TextBox)
                                {
                                    TextBox tx = this.EditingControl as TextBox;
                                    int tmp = tx.SelectionStart;
                                    tx.Text = tx.Text.Insert(tx.SelectionStart,
                                                        Environment.NewLine);
                                    tx.SelectionStart = tmp + Environment.NewLine.Length;

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

                                    return true;


                                }
                            }
                        }
                        return false;
                }
                return base.ProcessDataGridViewKey(e);
            }
        }

To make the Tab key work in edit mode, you have to set the AcceptsTab property to
true for the TextBox as well.

       
Code Block

        void dataGridView1_EditingControlShowing(object


sender,DataGridViewEditingControlShowingEventArgs e)
        {
            if (e.Control is TextBox)
            {
                TextBox tb = e.Control as TextBox;
                tb.AcceptsTab = true;
            }
        }

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1898048&SiteID=1

Zhi-Xin Ye Wednesday, December 05, 2007 6:34 AM

13.    How to make the DataGridView show gridlines in all display areas?

0 By default, the DataGridView leaves a gray background if the DataGridView size is


Sign In larger than the data display area size which is needed. To avoid this, we can derive
to Vote from the DataGridView and override its OnPaint method to draw extra lines in the
non-data area. The following sample demonstrates how to do this.

 
Code Block
       
        public class GridLineDataGridView : DataGridView
        {
            public GridLineDataGridView()
            {
                this.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            }
            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
 
                int rowHeight = this.RowTemplate.Height;
 
                int h = this.ColumnHeadersHeight + rowHeight * this.RowCount;
                int imgWidth = this.Width - 2;
                Rectangle rFrame = new Rectangle(0, 0, imgWidth, rowHeight);
                Rectangle rFill = new Rectangle(1, 1, imgWidth - 2, rowHeight);
                Rectangle rowHeader = new Rectangle(2, 2, this.RowHeadersWidth - 3,
rowHeight);
 
                Pen pen = new Pen(this.GridColor, 1);
 

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

                Bitmap rowImg = new Bitmap(imgWidth, rowHeight);


                Graphics g = Graphics.FromImage(rowImg);
                g.DrawRectangle(pen, rFrame);
                g.FillRectangle(new SolidBrush(this.DefaultCellStyle.BackColor), rFill);
                g.FillRectangle(new SolidBrush
                   (this.RowHeadersDefaultCellStyle.BackColor), rowHeader);
 
                int w = this.RowHeadersWidth - 1;
                for (int j = 0; j < this.ColumnCount; j++)
                {
                    g.DrawLine(pen, new Point(w, 0), new Point(w, rowHeight));
                    w += this.Columns[j].Width;
                }
 
                int loop = (this.Height - h) / rowHeight;
                for (int j = 0; j < loop + 1; j++)
                {
                    e.Graphics.DrawImage(rowImg, 1, h + j * rowHeight);
                }
            }
        }

Related threads:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2241055&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1947368&SiteID=1

Zhi-Xin Ye Wednesday, December 05, 2007 7:45 AM

14. How do I prevent a particular cell from being editable?


0
Sign In       The ReadOnly property indicates whether the data displayed by the cell can be
to Vote edited. You can set ReadOnly for individual cells, or you can make an entire row or
column of cells read-only by setting the DataGridViewRow.ReadOnly or
DataGridViewColumn.ReadOnly properties. By default, if a cell's parent row or column
is set to read-only, the child cells will adopt the same value.

      While you can navigate to a read-only cell, and you can set a read-only cell to be
the current cell, the content cannot be modified by the user. Note that the ReadOnly
property does not keep the cell from being modified programmatically. Also note that
ReadOnly does not affect whether the user can delete rows.

Zhi-Xin Ye Wednesday, December 05, 2007 7:47 AM

15.    How do I disable a cell?


0        While a cell can be read-only to prevent it from being editable, the DataGridView
Sign In does not have built-in support for disabling a cell. Normally the concept of "disabled"
to Vote means that the user cannot navigate to it and usually has a visual cue that it is
disabled.  There isn't any easy way to create the navigational side of disabled, but the
visual cue is something that can be done. While none of the built-in cell have a
disabled property, the following example extends the DataGridViewButtonCell and
implements a visual "disabled" state along with a corresponding disabled property.

Code Block

        public class DataGridViewDisableButtonColumn : DataGridViewButtonColumn

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

        {
            public DataGridViewDisableButtonColumn()
            {
                this.CellTemplate = new DataGridViewDisableButtonCell();
            }
        }
 
        public class DataGridViewDisableButtonCell : DataGridViewButtonCell
        {
            private bool enabledValue;
            public bool Enabled
            {
                get
                {
                    return enabledValue;
                }
                set
                {
                    enabledValue = value;
                }
            }
 
            // Override the Clone method so that the Enabled property is copied.
            public override object Clone()
            {
                DataGridViewDisableButtonCell cell =
                    (DataGridViewDisableButtonCell)base.Clone();
                cell.Enabled = this.Enabled;
                return cell;
            }
 
            // By default, enable the button cell.
            public DataGridViewDisableButtonCell()
            {
                this.enabledValue = true;
            }
 
            protected override void Paint(Graphics graphics,
                Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
                DataGridViewElementStates elementState, object value,
                object formattedValue, string errorText,
                DataGridViewCellStyle cellStyle,
                DataGridViewAdvancedBorderStyle advancedBorderStyle,
                DataGridViewPaintParts paintParts)
            {
                // The button cell is disabled, so paint the border, 
                // background, and disabled button for the cell.
                if (!this.enabledValue)
                {
                    // Draw the cell background, if specified.
                    if ((paintParts & DataGridViewPaintParts.Background) ==
                        DataGridViewPaintParts.Background)
                    {
                        SolidBrush cellBackground =
                            new SolidBrush(cellStyle.BackColor);
                        graphics.FillRectangle(cellBackground, cellBounds);
                        cellBackground.Dispose();
                    }
 
                    // Draw the cell borders, if specified.
                    if ((paintParts & DataGridViewPaintParts.Border) ==
                        DataGridViewPaintParts.Border)
                    {
                        PaintBorder(graphics, clipBounds, cellBounds, cellStyle,
                            advancedBorderStyle);
                    }
 
                    // Calculate the area in which to draw the button.
                    Rectangle buttonArea = cellBounds;
                    Rectangle buttonAdjustment =
                        this.BorderWidths(advancedBorderStyle);
                    buttonArea.X += buttonAdjustment.X;
                    buttonArea.Y += buttonAdjustment.Y;
                    buttonArea.Height -= buttonAdjustment.Height;
                    buttonArea.Width -= buttonAdjustment.Width;
 
                    // Draw the disabled button.               

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

                    ButtonRenderer.DrawButton(graphics, buttonArea,


                        PushButtonState.Disabled);
 
                    // Draw the disabled button text.
                    if (this.FormattedValue is String)
                    {
                        TextRenderer.DrawText(graphics,
                            (string)this.FormattedValue,
                            this.DataGridView.Font,
                            buttonArea, SystemColors.GrayText);
                    }
                }
                else
                {
                    // The button cell is enabled, so let the base class
                    // handle the painting.
                    base.Paint(graphics, clipBounds, cellBounds, rowIndex,
                        elementState, value, formattedValue, errorText,
                        cellStyle, advancedBorderStyle, paintParts);
                }
            }
        }
 

Zhi-Xin Ye Wednesday, December 05, 2007 7:51 AM

16. How do I show controls in all cells regardless of edit?

0
Sign In        The DataGridView control only supports displaying an actual control when a cell is
to Vote in edit mode. The DataGridView control is not designed to display multiple controls or
repeat a set of controls per row. The DataGridView control draws a representation of
the control when the cell is not being edited. This representation can be a detailed as
you want. For example, the DataGridViewButtonCell draws a button regardless of the
cell being in edit or not.

       However, you can add controls through DataGridView.Controls.Add() method, and
set their location and size to make them hosted in the cells, but showing controls in all
cells regardless of editing make no sense.

Zhi-Xin Ye Wednesday, December 05, 2007 7:53 AM

17. How do I handle the SelectedIndexChanged event?


0
Sign In      Sometimes it is helpful to know when a user has selected an item in the
to Vote ComboBox editing control. With a ComboBox on your form you would normally
handle the SelectedIndexChanged event. With the DataGridViewComboBox you can do
the same thing by using the DataGridView.EditingControlShowing event. The following
code example demonstrates how to do this. Note that the sample also demonstrates
how to keep multiple SelectedIndexChanged events from firing.

 
Code Block

        private void dataGridView1_EditingControlShowing(object sender,


                    DataGridViewEditingControlShowingEventArgs e)
        {

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

            ComboBox cb = e.Control as ComboBox;


            if (cb != null)
            {
                // first remove event handler to keep from attaching multiple:
                cb.SelectedIndexChanged -= new
                EventHandler(cb_SelectedIndexChanged);
 
                // now attach the event handler
                cb.SelectedIndexChanged += new
                EventHandler(cb_SelectedIndexChanged);
            }
        }
 
        void cb_SelectedIndexChanged(object sender, EventArgs e)
        {
            MessageBox.Show("Selected index changed");
        }
 

Zhi-Xin Ye Wednesday, December 05, 2007 7:59 AM

18. How do I show icon and text in the same cell?

0
Sign In      The DataGridView control does not have any built-in support for showing an icon
to Vote and text in the same cell. Through the different painting customization events, such as
the CellPainting event, you can easily display an icon next to the text in the cell.

     The following example extends the DataGridViewTextColumn and cell to paint an
image next to the text. The sample uses the DataGridViewCellStyle.Padding property to
adjust the text location and overrides the Paint method to paint an icon. This sample
can be simplified by handling the CellPainting event and performing similar code.

Code Block

        public class TextAndImageColumn : DataGridViewTextBoxColumn


        {
            private Image imageValue;
            private Size imageSize;
 
            public TextAndImageColumn()
            {
                this.CellTemplate = new TextAndImageCell();
            }
 
            public override object Clone()
            {
                TextAndImageColumn c = base.Clone() as TextAndImageColumn;
                c.imageValue = this.imageValue;
                c.imageSize = this.imageSize;
                return c;
            }
 
            public Image Image
            {
                get { return this.imageValue; }
                set
                {
                    if (this.Image != value)
                    {
                        this.imageValue = value;
                        this.imageSize = value.Size;
 

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

                        if (this.InheritedStyle != null)


                        {
                            Padding inheritedPadding = this.InheritedStyle.Padding;
                            this.DefaultCellStyle.Padding = new Padding(imageSize.Width,
                         inheritedPadding.Top, inheritedPadding.Right,
                         inheritedPadding.Bottom);
                        }
                    }
                }
            }
            private TextAndImageCell TextAndImageCellTemplate
            {
                get { return this.CellTemplate as TextAndImageCell; }
            }
            internal Size ImageSize
            {
                get { return imageSize; }
            }
        }
 

(see next post )

Zhi-Xin Ye Wednesday, December 05, 2007 8:00 AM

Code Block

0  
Sign In        public class TextAndImageCell : DataGridViewTextBoxCell
to Vote
        {
            private Image imageValue;
            private Size imageSize;
 
            public override object Clone()
            {
                TextAndImageCell c = base.Clone() as TextAndImageCell;
                c.imageValue = this.imageValue;
                c.imageSize = this.imageSize;
                return c;
            }
 
            public Image Image
            {
                get
                {
                    if (this.OwningColumn == null ||
                this.OwningTextAndImageColumn == null)
                    {
 
                        return imageValue;
                    }
                    else if (this.imageValue != null)
                    {
                        return this.imageValue;
                    }
                    else
                    {
                        return this.OwningTextAndImageColumn.Image;
                    }
                }
                set
                {
                    if (this.imageValue != value)
                    {
                        this.imageValue = value;
                        this.imageSize = value.Size;
 

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

                        Padding inheritedPadding = this.InheritedStyle.Padding;


                        this.Style.Padding = new Padding(imageSize.Width,
                        inheritedPadding.Top, inheritedPadding.Right,
                        inheritedPadding.Bottom);
                    }
                }
            }
            protected override void Paint(Graphics graphics, Rectangle clipBounds,
            Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState,
            object value, object formattedValue, string errorText,
            DataGridViewCellStyle cellStyle,
            DataGridViewAdvancedBorderStyle advancedBorderStyle,
            DataGridViewPaintParts paintParts)
            {
                // Paint the base content
                base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState,
                   value, formattedValue, errorText, cellStyle,
                   advancedBorderStyle, paintParts);
 
                if (this.Image != null)
                {
                    // Draw the image clipped to the cell.
                    System.Drawing.Drawing2D.GraphicsContainer container =
                    graphics.BeginContainer();
 
                    graphics.SetClip(cellBounds);
                    graphics.DrawImageUnscaled(this.Image, cellBounds.Location);
 
                    graphics.EndContainer(container);
                }
            }
 
            private TextAndImageColumn OwningTextAndImageColumn
            {
                get { return this.OwningColumn as TextAndImageColumn; }
            }
        }

Zhi-Xin Ye Wednesday, December 05, 2007 8:03 AM

19. How do I hide a column?

0      Sometimes you will want to display only some of the columns that are available in
Sign In a DataGridView. For example, you might want to show an employee salary column to
to Vote users with management credentials while hiding it from other users.

To hide a column programmatically

In the DataGridView control, the column's Visible property determines whether the
column is displayed.

To hide a column using the designer

1) Choose Edit Columns from the control's smart tag.


2) Select a column from the Selected Columns list.
3) In the Column Properties grid, set the Visible property to false.

Edited by Zhi-Xin Ye Wednesday, December 31, 2008 10:05 AM test


Edited by Zhi-Xin Ye Wednesday, December 31, 2008 10:09 AM test
 

Zhi-Xin Ye Wednesday, December 05, 2007 8:06 AM

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

20. How do I prevent the user from sorting on a column?


0 In the DataGridView control, text box columns use automatic sorting by default, while
Sign In other column types are not sorted automatically. Sometimes you will want to override
to Vote these defaults.

In the DataGridView control, the SortMode property value of a column determines its
sorting behavior.

Zhi-Xin Ye Wednesday, December 05, 2007 8:10 AM

21. How do I sort on multiple columns?


0       By default the DataGridView control does not provide sorting on multiple columns.
Sign In Depending upon if the DataGridView is databound or not, you can provide additional
to Vote support for sorting on multiple columns.

       21.1 Databound DataGridView

      When the DataGridView is databound the datasource can be sorted on multiple
columns and the DataGridView will respect that sorting, but the only the first sorted
column will display the sort glyph. In addition, the SortedColumn property will only
return the first sorted column. 

      Some datasources have built in support for sorting on multiple columns. If your
datasource implements IBindingListView and provides support for the Sort property,
then using it will provide support for multi-column sorting. To indicate in the grid that
multiple columns are sorted on, manually set a column's SortGlyphDirection to
properly indicate that the column is sorted. 

      The following example uses a DataTable and sets the default view's Sort property
to sort on the second and third columns. The example also demonstrates setting the
column's SortGlyphDirection. The example assumes that you have a DataGridView and
a BindingSource component on your form:

Code Block

DataTable dt = new DataTable();


dt.Columns.Add("C1", typeof(int));
dt.Columns.Add("C2", typeof(string));
dt.Columns.Add("C3", typeof(string));
 
dt.Rows.Add(1, "1", "Test1");
dt.Rows.Add(2, "2", "Test2");
dt.Rows.Add(2, "2", "Test1");
dt.Rows.Add(3, "3", "Test3");
dt.Rows.Add(4, "4", "Test4");
dt.Rows.Add(4, "4", "Test3");
 
DataView view = dt.DefaultView;
view.Sort = "C2 ASC, C3 ASC";
bindingSource.DataSource = view;
 
DataGridViewTextBoxColumn col0 = new
DataGridViewTextBoxColumn();
col0.DataPropertyName = "C1";
dataGridView1.Columns.Add(col0);
col0.SortMode = DataGridViewColumnSortMode.Programmatic;
col0.HeaderCell.SortGlyphDirection = SortOrder.None;
 
DataGridViewTextBoxColumn col1 = new
DataGridViewTextBoxColumn();
col1.DataPropertyName = "C2";
dataGridView1.Columns.Add(col1);
col1.SortMode = DataGridViewColumnSortMode.Programmatic;

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

col1.HeaderCell.SortGlyphDirection = SortOrder.Ascending;
 
DataGridViewTextBoxColumn col2 = new
DataGridViewTextBoxColumn();
col2.DataPropertyName = "C3";
dataGridView1.Columns.Add(col2);
col2.SortMode = DataGridViewColumnSortMode.Programmatic;
col2.HeaderCell.SortGlyphDirection = SortOrder.Ascending;

(see next post for the remainder)

Zhi-Xin Ye Wednesday, December 05, 2007 8:14 AM

      21.2 Unbound DataGridView


0      To provide support for sorting on multiple columns you can handle the
Sign In SortCompare event or call the Sort(IComparer) overload of the Sort method for
to Vote greater sorting flexibility.

           21.2.1 Custom Sorting Using the SortCompare Event


 
         The following code example demonstrates custom sorting using a SortCompare
event handler. The selected DataGridViewColumn is sorted and, if there are duplicate
values in the column, the ID column is used to determine the final order.

Code Block
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
 
class Form1 : Form
{
    private DataGridView dataGridView1 = new DataGridView();
 
    // Establish the main entry point for the application.
    [STAThreadAttribute()]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form1());
    }
 
    public Form1()
    {
        // Initialize the form.
        // This code can be replaced with designer generated code.
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.Dock = DockStyle.Fill;
        dataGridView1.SortCompare += new DataGridViewSortCompareEventHandler(
            this.dataGridView1_SortCompare);
        Controls.Add(this.dataGridView1);
        this.Text = "DataGridView.SortCompare demo";
 
        PopulateDataGridView();
    }
 
    // Replace this with your own population code.
    public void PopulateDataGridView()
    {
        // Add columns to the DataGridView.
        dataGridView1.ColumnCount = 3;
 

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

        // Set the properties of the DataGridView columns.


        dataGridView1.Columns[0].Name = "ID";
        dataGridView1.Columns[1].Name = "Name";
        dataGridView1.Columns[2].Name = "City";
        dataGridView1.Columns["ID"].HeaderText = "ID";
        dataGridView1.Columns["Name"].HeaderText = "Name";
        dataGridView1.Columns["City"].HeaderText = "City";
 
        // Add rows of data to the DataGridView.
        dataGridView1.Rows.Add(new string[] { "1", "Parker", "Seattle" });
        dataGridView1.Rows.Add(new string[] { "2", "Parker", "New York" });
        dataGridView1.Rows.Add(new string[] { "3", "Watson", "Seattle" });
        dataGridView1.Rows.Add(new string[] { "4", "Jameson", "New Jersey" });
        dataGridView1.Rows.Add(new string[] { "5", "Brock", "New York" });
        dataGridView1.Rows.Add(new string[] { "6", "Conner", "Portland" });
 
        // Autosize the columns.
        dataGridView1.AutoResizeColumns();
    }
 
    private void dataGridView1_SortCompare(object sender,
        DataGridViewSortCompareEventArgs e)
    {
        // Try to sort based on the cells in the current column.
        e.SortResult = System.String.Compare(
            e.CellValue1.ToString(), e.CellValue2.ToString());
 
        // If the cells are equal, sort based on the ID column.
        if (e.SortResult == 0 && e.Column.Name != "ID")
        {
            e.SortResult = System.String.Compare(
                dataGridView1.Rows[e.RowIndex1].Cells["ID"].Value.ToString(),
                dataGridView1.Rows[e.RowIndex2].Cells["ID"].Value.ToString());
        }
        e.Handled = true;
    }
}

(see next post for the remainder)

Zhi-Xin Ye Wednesday, December 05, 2007 8:16 AM

        21.2.2 Custom Sorting Using the IComparer Interface


0       The following code example demonstrates custom sorting using the
Sign In Sort(IComparer) overload of the Sort method, which takes an implementation of the
to Vote IComparer interface to perform a multiple-column sort.

Code Block
using System;
using System.Drawing;
using System.Windows.Forms;
 
class Form1 : Form
{
    private DataGridView DataGridView1 = new DataGridView();
    private FlowLayoutPanel FlowLayoutPanel1 = new FlowLayoutPanel();
    private Button Button1 = new Button();
    private RadioButton RadioButton1 = new RadioButton();
    private RadioButton RadioButton2 = new RadioButton();
 
    // Establish the main entry point for the application.
    [STAThreadAttribute()]
    public static void Main()

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

    {
        Application.Run(new Form1());
    }
 
    public Form1()
    {
        // Initialize the form.
        // This code can be replaced with designer generated code.
        AutoSize = true;
        Text = "DataGridView IComparer sort demo";
 
        FlowLayoutPanel1.FlowDirection = FlowDirection.TopDown;
        FlowLayoutPanel1.Location = new System.Drawing.Point(304, 0);
        FlowLayoutPanel1.AutoSize = true;
 
        FlowLayoutPanel1.Controls.Add(RadioButton1);
        FlowLayoutPanel1.Controls.Add(RadioButton2);
        FlowLayoutPanel1.Controls.Add(Button1);
 
        Button1.Text = "Sort";
        RadioButton1.Text = "Ascending";
        RadioButton2.Text = "Descending";
        RadioButton1.Checked = true;
 
        Controls.Add(FlowLayoutPanel1);
        Controls.Add(DataGridView1);
    }
 
    protected override void OnLoad(EventArgs e)
    {
        PopulateDataGridView();
        Button1.Click += new EventHandler(Button1_Click);
 
        base.OnLoad(e);
    }
 
    // Replace this with your own code to populate the DataGridView.
    private void PopulateDataGridView()
    {
 
        DataGridView1.Size = new Size(300, 300);
 
        // Add columns to the DataGridView.
        DataGridView1.ColumnCount = 2;
 
        // Set the properties of the DataGridView columns.
        DataGridView1.Columns[0].Name = "First";
        DataGridView1.Columns[1].Name = "Last";
        DataGridView1.Columns["First"].HeaderText = "First Name";
        DataGridView1.Columns["Last"].HeaderText = "Last Name";
        DataGridView1.Columns["First"].SortMode =
            DataGridViewColumnSortMode.Programmatic;
        DataGridView1.Columns["Last"].SortMode =
            DataGridViewColumnSortMode.Programmatic;
 
        // Add rows of data to the DataGridView.
        DataGridView1.Rows.Add(new string[] { "Peter", "Parker" });
        DataGridView1.Rows.Add(new string[] { "James", "Jameson" });
        DataGridView1.Rows.Add(new string[] { "May", "Parker" });
        DataGridView1.Rows.Add(new string[] { "Mary", "Watson" });
        DataGridView1.Rows.Add(new string[] { "Eddie", "Brock" });
    }
 
    private void Button1_Click(object sender, EventArgs e)
    {
        if (RadioButton1.Checked == true)
        {
            DataGridView1.Sort(new RowComparer(SortOrder.Ascending));
        }
        else if (RadioButton2.Checked == true)
        {
            DataGridView1.Sort(new RowComparer(SortOrder.Descending));
        }
    }
 
    private class RowComparer : System.Collections.IComparer
    {

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

        private static int sortOrderModifier = 1;


 
        public RowComparer(SortOrder sortOrder)
        {
            if (sortOrder == SortOrder.Descending)
            {
                sortOrderModifier = -1;
            }
            else if (sortOrder == SortOrder.Ascending)
            {
                sortOrderModifier = 1;
            }
        }
 
        public int Compare(object x, object y)
        {
            DataGridViewRow DataGridViewRow1 = (DataGridViewRow)x;
            DataGridViewRow DataGridViewRow2 = (DataGridViewRow)y;
 
            // Try to sort based on the Last Name column.
            int CompareResult = System.String.Compare(
                DataGridViewRow1.Cells[1].Value.ToString(),
                DataGridViewRow2.Cells[1].Value.ToString());
 
            // If the Last Names are equal, sort based on the First Name.
            if (CompareResult == 0)
            {
                CompareResult = System.String.Compare(
                    DataGridViewRow1.Cells[0].Value.ToString(),
                    DataGridViewRow2.Cells[0].Value.ToString());
            }
            return CompareResult * sortOrderModifier;
        }
    }
}

Zhi-Xin Ye Wednesday, December 05, 2007 8:17 AM

22.   How do I perform drag and drop reorder of rows?


0 Drag and dropping to reorder rows is not built into the DataGridView, but following
Sign In standard drag and drop code you can easily add this functionality to the
to Vote DataGridView. The code fragment below shows how you can accomplish this. It
assumes that you have a DataGridView control on your form named dataGridView1
and that the grid's AllowDrop property is true and the necessary events are hooked up
to the correct event handlers.

Code Block
private Rectangle dragBoxFromMouseDown;
        private int rowIndexFromMouseDown;
        private int rowIndexOfItemUnderMouseToDrop;
        private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
        {
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                // If the mouse moves outside the rectangle, start the drag.
                if (dragBoxFromMouseDown != Rectangle.Empty &&
                    !dragBoxFromMouseDown.Contains(e.X, e.Y))
                {
 
                    // Proceed with the drag and drop, passing in the list
item.                   

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

                    DragDropEffects dropEffect = dataGridView1.DoDragDrop(


                    dataGridView1.Rows[rowIndexFromMouseDown],
                    DragDropEffects.Move);
                }
            }
        }
 
        private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
        {
            // Get the index of the item the mouse is below.
            rowIndexFromMouseDown = dataGridView1.HitTest(e.X, e.Y).RowIndex;
 
            if (rowIndexFromMouseDown != -1)
            {
                // Remember the point where the mouse down occurred.
                // The DragSize indicates the size that the mouse can move
                // before a drag event should be started.               
                Size dragSize = SystemInformation.DragSize;
 
                // Create a rectangle using the DragSize, with the mouse position being
                // at the center of the rectangle.
                dragBoxFromMouseDown = new Rectangle(new Point(e.X -
(dragSize.Width / 2),
                                                               e.Y - (dragSize.Height / 2)),
                                    dragSize);
            }
            else
                // Reset the rectangle if the mouse is not over an item in the ListBox.
                dragBoxFromMouseDown = Rectangle.Empty;
        }
 
        private void dataGridView1_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }
 
        private void dataGridView1_DragDrop(object sender, DragEventArgs e)
        {
            // The mouse locations are relative to the screen, so they must be
            // converted to client coordinates.
            Point clientPoint = dataGridView1.PointToClient(new Point(e.X, e.Y));
 
            // Get the row index of the item the mouse is below.
            rowIndexOfItemUnderMouseToDrop =
                dataGridView1.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
 
            // If the drag operation was a move then remove and insert the row.
            if (e.Effect == DragDropEffects.Move)
            {
                DataGridViewRow rowToMove = e.Data.GetData(
                    typeof(DataGridViewRow)) as DataGridViewRow;
                dataGridView1.Rows.RemoveAt(rowIndexFromMouseDown);
                dataGridView1.Rows.Insert(rowIndexOfItemUnderMouseToDrop,
rowToMove);
 
            }
        }

Zhi-Xin Ye Wednesday, December 05, 2007 8:19 AM

23. How do I make the last column wide enough to occupy all the remaining
client area of the grid?
0
Sign In

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

to Vote By setting the AutoSizeMode for the last column to Fill the column will size itself to
fill in the remaining client area of the grid. Optionally you can set the last column's
MinimumWidth if you want to keep the column from sizing too small.

Zhi-Xin Ye Wednesday, December 05, 2007 8:20 AM

24.    How do I have the cell text wrap?


0 By default, text in a DataGridViewTextBoxCell does not wrap. This can be controlled via
Sign In the WrapMode property on the cell style (e.g.
to Vote DataGridView.DefaultCellStyle.WrapMode). Set the WrapMode property of a
DataGridViewCellStyle to one of the DataGridViewTriState enumeration values.
The following code example uses the DataGridView.DefaultCellStyle property to set the
wrap mode for the entire control.

      
Code Block

this.dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;

Zhi-Xin Ye Wednesday, December 05, 2007 8:22 AM

25.   How do I make the image column not show any images?

0
Sign In By default the image column and cell convert null values to the standard "X" image .
to Vote You can make no image show up by changing the column’s NullValue property to null.
The following code example sets the NullValue for an image column:

       this.dataGridViewImageColumn1.DefaultCellStyle.NullValue = null;

Zhi-Xin Ye Wednesday, December 05, 2007 8:27 AM

26. How do I enable typing in the combo box cell?


0       By default a DataGridViewComboBoxCell does not support typing into the cell.
Sign In There are reasons though that typing into the combo box works well for your
to Vote application. To enable this, two things have to be done. First the DropDownStyle
property of the ComboBox editing control needs to be set to DropDown to enable
typing in the combo box. The second thing that needs to be done is to ensure that
the value that the user typed into the cell is added to the combo box items collection.
This is due to the requirement  that a combo box cells value must be in the items
collection or else a DataError event is raised. The appropriate place to add the value to
the items collection is in the CellValidating event handler.

Code Block

        private void dataGridView1_CellValidating(object sender,

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

                 DataGridViewCellValidatingEventArgs e)
        {
            if (e.ColumnIndex == comboBoxColumn.DisplayIndex)
            {
                if (!this.comboBoxColumn.Items.Contains(e.FormattedValue))
                {
                    this.comboBoxColumn.Items.Add(e.FormattedValue);
                }
            }
        }
 
        private void dataGridView1_EditingControlShowing(object sender,
                DataGridViewEditingControlShowingEventArgs e)
        {
            if (this.dataGridView1.CurrentCellAddress.X ==
comboBoxColumn.DisplayIndex)
            {
                ComboBox cb = e.Control as ComboBox;
                if (cb != null)
                {
                    cb.DropDownStyle = ComboBoxStyle.DropDown;
                }
            }
        }

Zhi-Xin Ye Wednesday, December 05, 2007 8:30 AM

27. How do I have a combo box column display a sub set of data based upon the
value of a different combo box column?
0
Sign In      Sometimes data that you want to display in the DataGridView has a relationship
to Vote between two tables such as a category and subcategory. You want to let the user
select the category and then choose between a subcategory based upon the category.
This is possible with the DataGridView by using two combo box columns. To enable
this, two versions of the filtered list (subcategory) needs to be created. One list has no
filter applied while the other one will be filtered only when the user is editing a
subcategory cell. Two lists are required due to the requirement  that a combo box cells
value must be in the items collection or else a DataError event is raised. In this case,
since all combo box cells in the column use the same datasource if you filter the
datasource for one row then a combo box cell in another row might not have its value
visible in the datasource, thus causing a DataError event.

     The below example uses the Northwind database to display related data from the
Territory and Region tables (a territory is in a specific region.) Using the category and
subcategory concept, the Region is the category and the Territory is the subcategory.

Code Block

        private void Form1_Load(object sender, EventArgs e)


        {
            this.territoriesTableAdapter.Fill(this.northwindDataSet.Territories);
            this.regionTableAdapter.Fill(this.northwindDataSet.Region);
 
            // Setup BindingSource for filtered view.
            filteredTerritoriesBS = new BindingSource();
            DataView dv = new DataView(northwindDataSet.Tables["Territories"]);
            filteredTerritoriesBS.DataSource = dv;
 
        }
 
        private void dataGridView1_CellBeginEdit(object sender,
                 DataGridViewCellCancelEventArgs e)
        {
            if (e.ColumnIndex == territoryComboBoxColumn.Index)

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

            {
                // Set the combobox cell datasource to the filtered BindingSource
                DataGridViewComboBoxCell dgcb =
(DataGridViewComboBoxCell)dataGridView1
                                [e.ColumnIndex, e.RowIndex];
                dgcb.DataSource = filteredTerritoriesBS;
 
                // Filter the BindingSource based upon the region selected
                this.filteredTerritoriesBS.Filter = "RegionID = " +
                    this.dataGridView1[e.ColumnIndex - 1, e.RowIndex].Value.ToString();
            }
        }
 
        private void dataGridView1_CellEndEdit(object sender,
DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == this.territoryComboBoxColumn.Index)
            {
                // Reset combobox cell to the unfiltered BindingSource
                DataGridViewComboBoxCell dgcb =
(DataGridViewComboBoxCell)dataGridView1
                                [e.ColumnIndex, e.RowIndex];
                dgcb.DataSource = territoriesBindingSource; //unfiltered
 
                this.filteredTerritoriesBS.RemoveFilter();
            }
        }

Zhi-Xin Ye Wednesday, December 05, 2007 8:33 AM

28. How do I show the error icon when the user is editing the cell?

0 Sometimes when using the error text and icon feature you want an immediate
Sign In feedback to the user that something that they typed into a cell is incorrect. By default
to Vote when setting the ErrorText property the error icon will not appear if the cell is in edit
mode such as a text box or combo box cell.

The below sample demonstrates how you can set a cell's padding in the CellValidating
event to provide spacing for the error icon. Since padding by default affects the
location of the error icon the sample uses the CellPainting to move the position of the
icon for painting. Lastly, the sample uses the tooltip control to display a custom tooltip
when the mouse is over the cell to indicate what the problem is. This sample could
also be written as a custom cell that overrides GetErrorIconBounds method to provide
a location for the error icon that was independent of the padding.  

Code Block

 
private ToolTip errorTooltip;
private Point cellInError = new Point(-2, -2);
public Form1()
{
    InitializeComponent();
    dataGridView1.ColumnCount = 3;
    dataGridView1.RowCount = 10;
}
 
private void dataGridView1_CellValidating(object sender,
DataGridViewCellValidatingEventArgs e)
{
    if (dataGridView1.IsCurrentCellDirty)
    {
        if (e.FormattedValue.ToString() == "BAD")
        {
            DataGridViewCell cell = dataGridView1[e.ColumnIndex,

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

e.RowIndex];
            cell.ErrorText = "Invalid data entered in cell";
 
            // increase padding for icon. This moves the editing control
            if (cell.Tag == null)
            {
                cell.Tag = cell.Style.Padding;
                cell.Style.Padding = new Padding(0, 0, 18, 0);
                cellInError = new Point(e.ColumnIndex, e.RowIndex);
            }
            if (errorTooltip == null)
            {
                errorTooltip = new ToolTip();
                errorTooltip.InitialDelay = 0;
                errorTooltip.ReshowDelay = 0;
                errorTooltip.Active = false;
            }
 
            e.Cancel = true;
        }
    }
}
 
private void dataGridView1_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
    if (dataGridView1.IsCurrentCellDirty &&
!String.IsNullOrEmpty(e.ErrorText))
    {
        // paint everything except error icon
        e.Paint(e.ClipBounds, DataGridViewPaintParts.All &
                        ~(DataGridViewPaintParts.ErrorIcon));
 
        // now move error icon over to fill in the padding space
        GraphicsContainer container = e.Graphics.BeginContainer();
        e.Graphics.TranslateTransform(18, 0);
        e.Paint(this.ClientRectangle, DataGridViewPaintParts.ErrorIcon);
        e.Graphics.EndContainer(container);
 
        e.Handled = true;
    }
}
 
private void dataGridView1_CellEndEdit(object sender,
DataGridViewCellEventArgs e)
{
    if (dataGridView1[e.ColumnIndex, e.RowIndex].ErrorText !=
String.Empty)
    {
        DataGridViewCell cell = dataGridView1[e.ColumnIndex, e.RowIndex];
        cell.ErrorText = String.Empty;
        cellInError = new Point(-2,-2);
 
        // restore padding for cell. This moves the editing control
        cell.Style.Padding = (Padding)cell.Tag;
 
        // hide and dispose tooltip
        if (errorTooltip != null)
        {
            errorTooltip.Hide(dataGridView1);
            errorTooltip.Dispose();
            errorTooltip = null;
        }
    }
}
 
// show and hide the tooltip for error
private void dataGridView1_CellMouseMove(object sender,
                        DataGridViewCellMouseEventArgs e)
{
    if (cellInError.X == e.ColumnIndex &&
        cellInError.Y == e.RowIndex)
    {
        DataGridViewCell cell = dataGridView1[e.ColumnIndex, e.RowIndex];
 
        if (cell.ErrorText != String.Empty)
        {

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

            if (!errorTooltip.Active)
            {
                errorTooltip.Show(cell.ErrorText, dataGridView1, 1000);
            }
            errorTooltip.Active = true;
        }
    }
}
 
private void dataGridView1_CellMouseLeave(object sender,
DataGridViewCellEventArgs e)
{
    if (cellInError.X == e.ColumnIndex &&
        cellInError.Y == e.RowIndex)
    {
        if (errorTooltip.Active)
        {
            errorTooltip.Hide(dataGridView1);
            errorTooltip.Active = false;
        }
    }
}

Zhi-Xin Ye Wednesday, December 05, 2007 8:35 AM

29. How do I show unbound data along with bound data?

0 The data you display in the DataGridView control will normally come from a data
Sign In source of some kind, but you might want to display a column of data that does not
to Vote come from the data source. This kind of column is called an unbound column.
Unbound columns can take many forms. As discussed in the data section above, you
can use virtual mode to display additional data along with bound data.

The following code example demonstrates how to create an unbound column of check
box cells to enable the user to select database records to process. The grid is put into
virtual mode and responds to the necessary events. The selected records are kept by
ID in a dictionary to allow the user to sort the content but not lose the checked rows.

Code Block

private System.Collections.Generic.Dictionary<int, bool>


checkState;
private void Form1_Load(object sender, EventArgs e)
{
    dataGridView1.AutoGenerateColumns = false;
    dataGridView1.DataSource = customerOrdersBindingSource;
 
    // The check box column will be virtual.
    dataGridView1.VirtualMode = true;
    dataGridView1.Columns.Insert(0, new
DataGridViewCheckBoxColumn());
 
    // Initialize the dictionary that contains the boolean check state.
    checkState = new Dictionary<int, bool>();
}
private void dataGridView1_CellValueChanged(object sender,
DataGridViewCellEventArgs e)
{
    // Update the status bar when the cell value changes.
    if (e.ColumnIndex == 0 && e.RowIndex != -1)
    {
        // Get the orderID from the OrderID column.
        int orderID =
(int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;
        checkState[orderID] =
(bool)dataGridView1.Rows[e.RowIndex].Cells[0].Value;
 

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

}
 
private void dataGridView1_CellValueNeeded(object sender,
DataGridViewCellValueEventArgs e)
{
    // Handle the notification that the value for a cell in the virtual
column
    // is needed. Get the value from the dictionary if the key exists.
 
    if (e.ColumnIndex == 0)
    {
        int orderID =
(int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;
        if (checkState.ContainsKey(orderID))
        {
            e.Value = checkState[orderID];
        }
        else
            e.Value = false;
    }
 
}
 
private void dataGridView1_CellValuePushed(object sender,
DataGridViewCellValueEventArgs e)
{
    // Handle the notification that the value for a cell in the virtual
column
    // needs to be pushed back to the dictionary.
 
    if (e.ColumnIndex == 0)
    {
        // Get the orderID from the OrderID column.
        int orderID =
(int)dataGridView1.Rows[e.RowIndex].Cells["OrderID"].Value;
 
        // Add or update the checked value to the dictionary
depending on if the
        // key (orderID) already exists.
        if (!checkState.ContainsKey(orderID))
        {
            checkState.Add(orderID, (bool)e.Value);
        }
        else
            checkState[orderID] = (bool)e.Value;
    }
}

Zhi-Xin Ye Wednesday, December 05, 2007 8:36 AM

30. How do I show data that comes from two tables?


0 The DataGridView does not provide any new features apart from virtual mode to
Sign In enable this. What you can do is use the JoinView class described in the following
to Vote article http://support.microsoft.com/default.aspx?scid=kb;en-us;325682. Using this class
you can join two or more DataTables together. This JoinView can then be databound
to the DataGridView.

Zhi-Xin Ye Wednesday, December 05, 2007 8:38 AM

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

31. How do I show master-details?

0 One of the most common scenarios for using the DataGridView control is the
Sign In master/detail form, in which a parent/child relationship between two database tables is
to Vote displayed. Selecting rows in the master table causes the detail table to update with
the corresponding child data.

Implementing a master/detail form is easy using the interaction between the


DataGridView control and the BindingSource component. The below sample will show
two related tables in the Northwind SQL Server sample database: Customers and
Orders. By selecting a customer in the master DataGridView all the orders for the
customer will appear in the detail DataGridView.

Code Block
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
 
public class Form1 : System.Windows.Forms.Form
{
    private DataGridView masterDataGridView = new DataGridView();
    private BindingSource masterBindingSource = new BindingSource();
    private DataGridView detailsDataGridView = new DataGridView();
    private BindingSource detailsBindingSource = new BindingSource();
 
    [STAThreadAttribute()]
    public static void Main()
    {
        Application.Run(new Form1());
    }
 
    // Initializes the form.
    public Form1()
    {
        masterDataGridView.Dock = DockStyle.Fill;
        detailsDataGridView.Dock = DockStyle.Fill;
 
        SplitContainer splitContainer1 = new SplitContainer();
        splitContainer1.Dock = DockStyle.Fill;
        splitContainer1.Orientation = Orientation.Horizontal;
        splitContainer1.Panel1.Controls.Add(masterDataGridView);
        splitContainer1.Panel2.Controls.Add(detailsDataGridView);
 
        this.Controls.Add(splitContainer1);
        this.Load += new System.EventHandler(Form1_Load);
        this.Text = "DataGridView master/detail demo";
    }
 
    private void Form1_Load(object sender, System.EventArgs e)
    {
        // Bind the DataGridView controls to the BindingSource
        // components and load the data from the database.
        masterDataGridView.DataSource = masterBindingSource;
        detailsDataGridView.DataSource = detailsBindingSource;
        GetData();
 
        // Resize the master DataGridView columns to fit the newly loaded data.
        masterDataGridView.AutoResizeColumns();
 
        // Configure the details DataGridView so that its columns automatically
        // adjust their widths when the data changes.
        detailsDataGridView.AutoSizeColumnsMode =
            DataGridViewAutoSizeColumnsMode.AllCells;
    }
 
    private void GetData()
    {
        try
        {
            // Specify a connection string. Replace the given value with a
            // valid connection string for a Northwind SQL Server sample
            // database accessible to your system.

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

            String connectionString =


                "Integrated Security=SSPI;Persist Security Info=False;" +
                "Initial Catalog=Northwind;Data Source=localhost";
            SqlConnection connection = new SqlConnection(connectionString);
 
            // Create a DataSet.
            DataSet data = new DataSet();
            data.Locale = System.Globalization.CultureInfo.InvariantCulture;
 
            // Add data from the Customers table to the DataSet.
            SqlDataAdapter masterDataAdapter = new
                SqlDataAdapter("select * from Customers", connection);
            masterDataAdapter.Fill(data, "Customers");
 
            // Add data from the Orders table to the DataSet.
            SqlDataAdapter detailsDataAdapter = new
                SqlDataAdapter("select * from Orders", connection);
            detailsDataAdapter.Fill(data, "Orders");
 
            // Establish a relationship between the two tables.
            DataRelation relation = new DataRelation("CustomersOrders",
                data.Tables["Customers"].Columns["CustomerID"],
                data.Tables["Orders"].Columns["CustomerID"]);
            data.Relations.Add(relation);
 
            // Bind the master data connector to the Customers table.
            masterBindingSource.DataSource = data;
            masterBindingSource.DataMember = "Customers";
 
            // Bind the details data connector to the master data connector,
            // using the DataRelation name to filter the information in the
            // details table based on the current row in the master table.
            detailsBindingSource.DataSource = masterBindingSource;
            detailsBindingSource.DataMember = "CustomersOrders";
        }
        catch (SqlException)
        {
            MessageBox.Show("To run this example, replace the value of the " +
                "connectionString variable with a connection string that is " +
                "valid for your system.");
        }
    }
}

Zhi-Xin Ye Wednesday, December 05, 2007 8:40 AM

32. How do I show master-details in the same DataGridView?

0      The DataGridView does not provide any support for showing master-details data in
Sign In the same DataGridView. The previously shipped Windows Forms DataGrid control can
to Vote be a solution if this is something that you need.

Zhi-Xin Ye Wednesday, December 05, 2007 8:41 AM

33. How do I prevent sorting?


0      By setting the DataGridViewColumn.SortMode property you can disable the ability
Sign In for the user to sort on the given column. You can use Visual Studio 2005 to set this

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

to Vote property by right-clicking on the DataGridView and choosing the Edit Columns option.
Next select the column that you want to disable sorting for and set the SortMode
property to NotSortable.

Zhi-Xin Ye Wednesday, December 05, 2007 8:43 AM

34. How do I commit the data to the database when clicking on a toolstrip


button?
0
Sign In By default, toolbars and menus do not force validation for controls. Validation is a
to Vote required part of validating and updating the data in a bound control. Once the form
and all bound controls are validated, any current edits need to be committed. Finally,
the table adapter needs to push its changes back to the database. To do this, put the
following three lines in a click event handler on your form:

Code Block
       
        this.Validate();
        this.customersBindingSource.EndEdit();        
        this.customersTableAdapter.Update(this.northwindDataSet.Customers);
 

Zhi-Xin Ye Wednesday, December 05, 2007 8:45 AM

35. How do I display a confirmation dialog when the user tries to delete a row?
0       When the user selects a row in the DataGridView and hits the delete key, the
Sign In UserDeletingRow event fires. You can prompt the user if they want to continue
to Vote deleting the row. It is recommended that you only do this if the row being deleted is
not the new row. Add the following code to the UserDeletingRow event handler to
perform this:

Code Block

if (!e.Row.IsNewRow)
{
    DialogResult response = MessageBox.Show("Are you sure?",
"Delete row?",
                         MessageBoxButtons.YesNo,
                         MessageBoxIcon.Question,
                         MessageBoxDefaultButton.Button2);
     if (response == DialogResult.No)
       e.Cancel = true;
}
 

© 2010 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement | Contact Us | Manage Your Profile

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]


Windows Forms Data Controls and Databinding FAQ

http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/a44622c0-74e1-463b-97b9-27b87513747e/[11/23/2010 4:44:36 PM]

You might also like