DataGridView cell editing

Hello,

In Microsoft Excel last versions, when editing a cell, if you are entering a value which size is larger than the cell size, the cell pass over the others and becomes dynamically as large as the value in order to see all the value (for example if it's a huge string it allows to see it entirely).
Does the DataGridView provides a feature like this ?

Thank you :)

Alex Bell

[390 byte] By [AlexBell] at [2007-12-16]
# 1
I have just discovered the DataGridViewTextBoxEditingControl control and I like to know if it allows to make what I want ?
I have a datagridview with textboxcolumns and I have tried to use this DataGridViewTextBoxEditingControl but I haven't successed :'(
If this control is the solution, could you show me simply how it works please ?
I haven't seen any sample :'( on how to use it...

Thank you very much for helping me.

AlexBell at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 2

The DataGridView doesn't do editing like Excel where the textbox grows larger when you add more text. You might be able to perform some advanced customziation. Check out the PositionEditingControl and PositionEditingPanel methods on DataGridViewCell. You will also need to return true from the RepositionEditingControlOnValueChange property on IDataGridViewEditingControl interface.

-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"

MarkRideout at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 3
Thank you very much for helping me :D
I've tried to use these functions but I haven't succeded...
Before to try to give a dynamic size to my EditingControl, I have tried to give it a fixed larger size than the CurrentCell size, but when I edit my cell, it keeps always the same behaviour...
I haven't successfully used the DataGridView.CurrentCell.PositionEditingControl method or the DataGridView.CurrentCell.PositionEditingPanel function.
The DataGridView.EditingControl property is just a get.
I'm just a student, I haven't a great experience and I haven't reflexes for do that easily...
Could you give me more explanations or examples of how to do that please ?
Thank you very much again ^^
AlexBell at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 4

The DataGridViewCell::PositionEditingControl and DataGridViewCell::PositionEditingPanel are virtual/overridable method. You need to sub-class the DataGridViewCell in order to get access (override) this method. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcn7/html/vaconInheritanceForBasicLanguage.asp for details on sub-classing using Visual Basic.

Note in your case you will want to sub-class the DataGridViewTextBoxCell.
Here is some code that will help:

Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim c As DataGridViewTextBoxColumn = New DataGridViewTextBoxColumn()
c.CellTemplate = New EditableMergedCell()
dataGridView1.Columns.Add(c)

c = New DataGridViewTextBoxColumn()
dataGridView1.Columns.Add(c)

dataGridView1.RowCount = 10

End Sub

End Class
Public Class EditableMergedCell
Inherits DataGridViewTextBoxCell

Public Overrides Sub PositionEditingControl(ByVal setLocation As Boolean, ByVal setSize As Boolean, ByVal cellBounds As System.Drawing.Rectangle, ByVal cellClip As System.Drawing.Rectangle, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal singleVerticalBorderAdded As Boolean, ByVal singleHorizontalBorderAdded As Boolean, ByVal isFirstDisplayedColumn As Boolean, ByVal isFirstDisplayedRow As Boolean)
MyBase.PositionEditingControl(setLocation, setSize, cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow)
End Sub
Public Overrides Function PositionEditingPanel(ByVal cellBounds As System.Drawing.Rectangle, ByVal cellClip As System.Drawing.Rectangle, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal singleVerticalBorderAdded As Boolean, ByVal singleHorizontalBorderAdded As Boolean, ByVal isFirstDisplayedColumn As Boolean, ByVal isFirstDisplayedRow As Boolean) As System.Drawing.Rectangle

' the cell rectangle is the bounds of the merged cell
Dim mergedRectangle As Rectangle = New Rectangle(cellBounds.Location, New Size(cellBounds.Width * 2, cellBounds.Height))

' the cell clip tells the grid how much of the merged cell is visible.
Dim mergedCellClip As Rectangle = New Rectangle(cellClip.Location, New Size(cellClip.Width * 2, cellClip.Height))
' -
' NOTE: This is how the grid determins the cell clip by default:
'Dim cellClip as Rectangle = cellBounds
'// Need to clip the zones of the frozen columns and rows and headers.
'If (not me.Columns(this.ptCurrentCell.X).Frozen) then
'
' Dim totalVisibleFrozenWidth as Integer = me.Columns.GetColumnsWidth(DataGridViewElementStates.Visible or DataGridViewElementStates.Frozen)
' If (not me.RightToLeftInternal) Then
' editingZone.X += totalVisibleFrozenWidth
' End If
' editingZone.Width = Math.Max(0, editingZone.Width - totalVisibleFrozenWidth)
'End If
'If ((me.Rows.GetRowState(this.ptCurrentCell.Y) and DataGridViewElementStates.Frozen) = 0) Then
' Dim totalVisibleFrozenHeight as Integer = me.Rows.GetRowsHeight(DataGridViewElementStates.Visible or DataGridViewElementStates.Frozen)
' editingZone.Y += totalVisibleFrozenHeight
'End If
'cellClip.Intersect(editingZone)
'

Return MyBase.PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow)
End Function
End Class

-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"

MarkRideout at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...
# 5

This is my implementation. There seems to be a few problems with wrapping but.

public class MemoCell: DataGridViewTextBoxCell

{

public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)

{

dataGridViewCellStyle.WrapMode = DataGridViewTriState.True;

base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);

}

public override void PositionEditingControl(bool setLocation, bool setSize, Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow)

{

base.PositionEditingControl(setLocation, setSize, cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow);

}

public override Rectangle PositionEditingPanel(Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow)

{

string value = (string)this.EditedFormattedValue;

Size maxSize = MaxSize(cellBounds.Location);

Size stringSize = MeasureString(value, cellStyle.Font, new SizeF((float)maxSize.Width, (float)maxSize.Height));

Console.WriteLine(stringSize);

Rectangle maxRectangle = new Rectangle(cellBounds.Location, MaxSize(cellBounds.Location));

int finalWidth = Math.Max(stringSize.Width, cellBounds.Width);

int finalHeight = Math.Max(stringSize.Height, cellBounds.Height);

Rectangle finalRectangle = new Rectangle(cellBounds.Location, new Size(finalWidth, finalHeight));

return base.PositionEditingPanel(finalRectangle, finalRectangle, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow);

}

public override Type EditType

{

get

{

return typeof(MemoTextBox);

}

}

public Size MeasureString(string value, Font font, SizeF layoutArea)

{

int characters,lines;

int lineHeight;

Graphics g = Graphics.FromHwnd(this.DataGridView.Handle);

lineHeight = g.MeasureString("MeasureString", font).ToSize().Height;

Size size = g.MeasureString(value, font, layoutArea, new StringFormat(StringFormatFlags.MeasureTrailingSpaces), out characters, out lines).ToSize();

Console.WriteLine("Characters{0}, lines{1}", characters, lines);

if (value.EndsWith(Environment.NewLine))

{

lines += 1;

}

size.Height = (lineHeight * lines);

return size;

}

private Size MaxSize(Point relativeLocation)

{

Size gridSize = this.DataGridView.Size;

int widthLeftover = gridSize.Width - relativeLocation.X;

int heightLeftover = gridSize.Height - relativeLocation.Y;

if (widthLeftover < 0

|| heightLeftover < 0)

{

throw new Exception("Tp can't be right!");

}

return new Size(widthLeftover, heightLeftover);

}

}

angrylala at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms Data Controls and Databinding...