This is a migrated thread and some comments may be shown as answers.

Keeping columns from being sized wider than the grid

2 Answers 100 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Bill
Top achievements
Rank 1
Bill asked on 02 Mar 2012, 11:44 PM
The issue at had is pinned columns - these stay unmoving on left side of the grid regardless of how you scroll, which means that if you stretch the right edge of a pinned column off the right side of the grid and let go, the edge is out of reach and you can't scroll over to get it, which effectively makes all columns to the right of it permanently unavailable.  This is obviously undesireable and I wish to avoid it.

The columns must remain pinned and resizeable - up to but not including the ability to drag the edge of the column off the edge of the grid.  Note that the allowable width is not fixed; it depends on both the width of the grid and the current position of the column within it.  The column might be the second or third columnin the grid, with the (also pinned) columns to its left being arbitrarily resizeable as well.

My plan in dealing with this would be to react to the ColumnWidthChanging or ColumnWidthChanged events and constrain/restore the column to a decent width, but I ran into an unexpected problem - I can't figure out how to get the location on-screen of a given column!  Without knowing where the column's left edge is I can't determine how wide to allow it to be.  Given a GridDataCellElement I could ask for its ControlBoundingRectangle, but I don't know how to get a GridDataCellElement from an arbitrary column.  The only one I seem to have direct access to is CurrentCell, which may or may not be in the column I'm interested in.

So - can anyone tell me how to get an arbitrary GridDataCellElement, or otherwise determine the pixel location of a column's left edge?

2 Answers, 1 is accepted

Sort by
0
Bill
Top achievements
Rank 1
answered on 06 Mar 2012, 06:40 PM
Alright, an update.  The following code appears to have the desired effect:
void radGridView_ColumnWidthChanged(object sender, System.Windows.Forms.ColumnWidthChangedEventArgs e)
{
    if (!radGridView.Columns[e.ColumnIndex].IsPinned) return;
 
    int left = 30;
    int right = radGridView.Width;
    for (int i = 0; i <= e.ColumnIndex-1; i++)
        left += radGridView.Columns[i].Width;
 
    if (radGridView.Columns[e.ColumnIndex].Width > right - left)
        radGridView.Columns[e.ColumnIndex].Width = right - left;
}

Despite the event name, this is actually called constantly while the column is being resized, which is odd but actually gives me a nicer-looking behavior as a result, since it prevents the user from even trying to drag the column beyond the limits.  (I was not able to replicate the effect with the more natural-seeming ColumnWidthChanging event because it was less amenable to me resizing the column mid-operation.)

There is one detail of this solution that could be improved upon, though: that 30 there.  It's meant to account for the width of the row selection area to the left of all columns; the number itself was chosen completely arbitrarily, and just happened to be large enough to account for the row selection area and to give me a pleasant-looking bit of extra margin besides.  This is dependent upon the width of that leftmost area never changing, though, and I dislike that sort of assumption.  How does one programmatically determine the width of that area?
0
Accepted
Jack
Telerik team
answered on 07 Mar 2012, 11:06 AM
Hello Bill,

I am glad to hear that you have found a solution for this issue.

You can get the row header width by using the RowHeaderColumnWidth property of GridTableElement:
int rowHeaderWidth = this.radGridView1.TableElement.RowHeaderColumnWidth;

Regarding your initial question, you can get the cell element for a certain column and row by using the GetCellElement method:
GridCellElement cell = this.radGridView1.TableElement.GetCellElement(this.radGridView1.MasterView.TableHeaderRow, this.radGridView1.Columns["Name"]);
if (cell != null)
{
    //...
}

However, please note that RadGridView uses UI virtualization and not all data cells have corresponding cell elements. When scrolling or applying data operations cell elements are reused for other cells. All this improves the performance and lowers the memory consumption. So, we do not recommend using the GetCellElement method.

When using a table layout, you can get cell dimensions by using the GetColumnOffset and GetColumnWidth methods of TableViewRowLayout. Here is a sample:
TableViewRowLayout tableLayout = this.radGridView1.TableElement.ViewElement.RowLayout as TableViewRowLayout;
int offset = tableLayout.GetColumnOffset(this.radGridView1.Columns[2]);
int width = tableLayout.GetColumnWidth(this.radGridView1.Columns[2]);

I hope this helps.

Kind regards,

Jack
the Telerik team
RadControls for WinForms Q1'12 release is now live! Check out what's new or download a free trial >>
Tags
GridView
Asked by
Bill
Top achievements
Rank 1
Answers by
Bill
Top achievements
Rank 1
Jack
Telerik team
Share this question
or