More DataGrid Samples: Custom Sorting, Drag and Drop of rows, Column Selection, and Single-click Editing
Jossef just wrote this great post on improving sorting in the DataGrid through a custom sort. Check it out here.
Ben Carter also added another sample that includes row drag-and-drop and column selection through cell selection. You can download that sample here.
One way to get single-click editing to work is to hack into one of the entry points for openning a cell/row for edit. Cells from all DataGridColumn types can be openned for edit by pressing F2 on a selected cell, double-clicking a cell that has not been selected, typing in a selected cell, or clicking on a cell that is already selected. An easy way to enable editing on a single-click is to catch the preview to the first mouse click of a cell and set it as selected. Then when the DataGridCell.OnAnyMouseLeftButtonDown is called it will see that the cell has already been selected so this click will open the cell for edit. Here is the code for it:
private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DataGridCell cell = sender as DataGridCell;
if (!cell.IsEditing)
{
// enables editing on single click
if (!cell.IsFocused)
cell.Focus();
if (!cell.IsSelected)
cell.IsSelected = true;
}
}
<Style TargetType="{x:Type dg:DataGridCell}">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown" />
</Style>
Comments
Anonymous
August 27, 2008
PingBack from http://hubsfunnywallpaper.cn/?p=2560Anonymous
August 27, 2008
When a new insert row is displayed is there a way to set the first cell or any cell in the new insertion row so the user can just start typing instead of having the user select the cell. What I'm trying to create is a easy way the the user to enter new data. Set the first cell in the insertion row in focus and ready for user input. The user then tabs to each blank cell enters data and when done press the return key. When the return key is press and the new insertion row is displayed I what to set focus to the first cell of the insertion row so the user can just continue to enter data. I'm maping the datagrid to a dataview so I get the event when a new row is entered into the dataview - return key pressed m_dvView[nDataViewIndex].Table.TableNewRow += EHTableNewRow;Anonymous
August 28, 2008
WAW, Here is one possible implementation for it. You can listen for the PreviewKeyDown event then have a dispatcher operation call a delegate after the DataGrid.KeyDown method is complete. Then after the operation you can update the current cell and focus. DataGrid_Standard.PreviewKeyDown += new KeyEventHandler(DataGrid_Standard_PreviewKeyDown); void DataGrid_Standard_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { int i = 0; foreach (object item in DataGrid_Standard.Items) { if (item == DataGrid_Standard.CurrentItem) { break; } i++; } DataGridRow row = GetRow(i); if (row.IsEditing) Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(OnKeyDown), new object[] { e }); } } private object OnKeyDown(object arg) { object[] arguments = arg as object[]; KeyEventArgs e = (KeyEventArgs)arguments[0]; if (e.Key == Key.Enter) { int i = 0; foreach (object item in DataGrid_Standard.Items) { if (item == DataGrid_Standard.CurrentItem) { break; } i++; } DataGridCell cell = GetCell(i, 0); if (DataGrid_Standard.SelectionUnit == DataGridSelectionUnit.Cell || DataGrid_Standard.SelectionUnit == DataGridSelectionUnit.CellOrRowHeader) { // have to deselect current cell(s) DataGrid_Standard.SelectedCells.Clear(); } // set focus to the first cell cell.Focus(); // select the first cell cell.IsSelected = true; // set the current cell to the first cell DataGrid_Standard.CurrentCell = new DataGridCellInfo(DataGrid_Standard.CurrentItem, DataGrid_Standard.Columns[0]); } return null; }Anonymous
August 29, 2008
Overview The DataGrid uses a set of DataGridColumns to describe how to display its data just like a GridViewAnonymous
August 29, 2008
If you haven’t already, you can download the binaries and source for the DataGrid here . DataGridComboBoxColumnAnonymous
September 01, 2008
Thanks for all your help. Im having problems with single click edit on a DataGrid bound to a DataView. The problem occurs when navigating from a cell that is in edit mode to another cell on the same row. The call to ConvertCellInfoToIndexes fails (Call Stack: OnIsSelectedChanged -> CellIsSelectedChanged -> AddValidatedCell -> ConvertCellInfoToIndexes), rowIndex ends up being -1 due to the modified DataRowView not being found (having a different RowState I guess): rowIndex = _owner.Items.IndexOf(cell.Item) When I replace that code with a loop through the rows, they are matched correctly, this works: for (int i = 0; i < _owner.Items.Count; i++) { if (_owner.Items[i] == cell.Item) { rowIndex = i; break; } } I also tried to force an EndEdit() on the underlying DataRow before trying to select the cell, but that made the insertion row to not showing up after edit is complete. This only occurs when binding to a DataTables DataView. Any ideas?Anonymous
September 02, 2008
PMN, This is a known issue and will be addressed in the final version of the WPF DataGrid. Sorry for the inconvenience. = ( Thanks, VinceAnonymous
September 05, 2008
Thanks for the help where is GetCell and GetRow defined?Anonymous
September 05, 2008
WAW, These are defined by the app author. Examples of them can be found on this thread, http://www.codeplex.com/wpf/Thread/View.aspx?ThreadId=34065Anonymous
September 16, 2008
As you might have heard, .NET Framework 3.5 SP1 and Visual Studio 2008 SP1 are out today! There are aAnonymous
September 19, 2008
In the v1 release (and CTP) of the WPF DataGrid there will be support for Clipboard.Copy but no supportAnonymous
September 19, 2008
Here is a short sample on how to create a tri-state sorting experience with the WPF DataGrid . In theAnonymous
September 19, 2008
There have been several questions on the WPF CodePlex discussion list relating to styling rows and columnsAnonymous
December 08, 2008
The comment has been removed