Tuesday, May 20, 2008

GridView editing mode and BeginEdit()

The user can enter the edit mode on the GridView control by clicking (or double-clicking) on a cell or by typing a key matching a valid input character for the current cell.

The methods EndEdit() and CancelEdit() allow you to exit the editing mode pragmatically. A call to EndEdit() will trigger the validation of the cell currently editing while a call to CancelEdit() will discard the value inputted in the editing control.

Something which is missing in the GridView is the possibility to enter the edit mode explicitly using some code.

Here is a workaround I have found: simulate a user pressing a key on the grid by calling the OnKeyDown event handler. A point to consider is that you do not want that key event to modify the content of the cell once it switches to edit mode, therefore we must send a special key code which is not associated to a displayable character. I have found the sequence [Ctrl]-[Ins] to be suitable for this purpose:



public class MyGridView : GridView
{
public void BeginEdit()
{
if (RowCount == 0 || ColumnCount == 0) return;
if (IsCurrentCellInEditMode) return;
if (!ContainsFocus) return;
OnKeyDown(new KeyEventArgs((Keys)131168)); // Ctrl + NumPad0
}
}


Hope it helps,
Fred

Saturday, May 17, 2008

GridView.CurrentCell and OnCurrentCellChanged

The GridView control allows to display and edit data in a grid. The CurrentCell property allows you to get and set the currently active cell. Visually, the current cell will by default display a focus border. Also, it will enter edit mode if you click on it using the mouse or press a valid input key on the keyboard (provided it is not read only).

One funny thing about the CurrentCell property is that, while the GridView provides a lot of events, there is currently (as of builds 1480 for Flash & 1551 for Silverlight) no OnCurrentCellChanged event that you can handle to be informed of a change of the active cell.

Well, in fact this is not really funny, especially if you need to be informed of a CurrentCell change... So, how can we workaround?

My first tentative was to use the OnRowStateChanged and OnColumnStateChanged events, but this prove to be not reliable as the behavior of these events depend of the grid SelectionMode. By example, if using FullRowSelect selection mode, the OnColumnStateChanged is never triggered.

After a lot of thinking, I came to the conclusion that if the CurrentCell changes, there is one thing that is very likely to happen: a repaint of the grid. Therefore I tried overriding OnPaint, and it seems to work quite well:



public class MyGridView : GridView
{
private Point previousCurrentCellAddress = Point.Empty;
public event EventHandler CurrentCellChanged;

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);

Point currentCellAddress = CurrentCellAddress;
if (currentCellAddress != previousCurrentCellAddress)
{
previousCurrentCellAddress = currentCellAddress;
OnCurrentCellChanged(EventArgs.Empty);
}
}

protected virtual void OnCurrentCellChanged(EventArgs e)
{
if (CurrentCellChanged != null)
CurrentCellChanged(this, e);
}
}


Hope this helps,
Fred

Introduction

I have been using GOA WinForms for Flash for quite some time and I would like to share with you my experience developing RIA using this tool.

Regards,
Fred