다음을 통해 공유


DataGrid Q&A #2

Q: How do I extend the DataGrid's furthest right column so that the column (or, at least, the column header) extends all the way to the right edge of the grid when the furthest right column is visible?

A: In all of my articles on the Windows Forms DataGrid control, I’ve emphasized that the key to getting the DataGrid to render the way you want it to lies in its styles. I've uploaded a zip file containing a solution that demonstrates how to do several different things:

  1. Use reflection to retrieve a reference to the default table style.
  2. Iterate over the default column style collection to calculate the widths of the columns.
  3. Calculate the width necessary for the rightmost column to span the remaining area of the visible grid.
  4. Ensure that when columns are resized, the desired stretching effect remains intact unless the resize would force the rightmost column to shrink under its defined width.
  5. Seamlessly handle the OnSizeChanged event.

The project has two files of interest: Form1.cs and MyCustomDataGrid.cs. The latter has all of the code that you’re going to be interested in. I’ve provided a fair amount of inline comments, but if there is any ambiguity, please feel free to let me know.

EDIT: The solution has been updated to include functionality to support column resizing when double clicking on column borders.

Comments

  • Anonymous
    January 18, 2005
    Hey Chris, this code rocks. I have just one situation in which I am able to out maneuver your clever manuevers: when the user double-clicks a column header to auto-size the columns, _WasColumnResized is not true. So I added the following to OnMouseDown, but it doesn't work in all cases. Any suggestions?

    protected override void OnMouseDown(MouseEventArgs e)
    {
    base.OnMouseDown( e );
    _IsMouseDown = true;


    if( e.Clicks > 1 && HitTest( e.X, e.Y ).Type == DataGrid.HitTestType.ColumnResize )
    { _WasColumnResized = true; }
    }
  • Anonymous
    January 18, 2005
    You were close. When the MouseDown event is raised, it will detect the clicks and repaint the grid before it hits your conditional expression, so that double click that you think is happening isn't. By moving the call to the base class' OnMouseDown method to below your condition, you ensure that you'll be able to evaluate the clicks before the base class gets to do anything with it. See the updated solution for a better explanation.
  • Anonymous
    January 18, 2005
    Regarding your edit, spot on! I would never have figured that out.
  • Anonymous
    June 17, 2005
    Troy Simpson was nice enough to point out and provide a fix for some visual inconsistencies with...