Data Grid Ex Support two new events
- Commit (An event that indicates that a selection is complete and has been made, effectively commit action.)
- Cancel (An event that indicates that the selection operation has been canceled)
Also supports single row double click.
Event Commit will be raise if user double click on row or press enter while row is selected where as event Cancel is fired if user click on Esc button.
Class DataGridEx :
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Collections; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Windows.Automation.Peers; using System.Linq; namespace XXX.YYY.Controls { public class DataGridEx : DataGrid { private DataGridRow _LastDataGridRow = null; private DataGridColumn _LastDataGridColumn = null; private DataGridCell _LastDataGridCell = null; private object _LastObject = null; private DateTime _LastClick = DateTime.MinValue; private double _DoubleClickTime = 1500; /// /// An event that indicates that a selection is complete and has been /// made, effectively a commit action. /// public event RoutedEventHandler Commit; /// /// An event that indicates that the selection operation has been /// canceled. /// public event RoutedEventHandler Cancel; /// /// Initializes a new instance of the DataGridEx class. /// public DataGridEx() { MouseLeftButtonUp += OnGridMouseLeftButtonUp; } private void OnGridMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { DateTime clickTime = DateTime.Now; DataGridRow currentRowClicked; DataGridColumn currentColumnClicked; DataGridCell currentCellClicked; object currentObject; //If we've found at least the row, if (GetDataGridCellByPosition(e.GetPosition(null), out currentRowClicked, out currentColumnClicked, out currentCellClicked, out currentObject)) { //And the current row is the same as the last row, and is within the timespan, consider it a double-click bool isDoubleClick = (currentRowClicked == _LastDataGridRow && clickTime.Subtract(_LastClick) <= TimeSpan.FromMilliseconds(_DoubleClickTime)); _LastDataGridRow = currentRowClicked; _LastDataGridColumn = currentColumnClicked; _LastDataGridCell = currentCellClicked; _LastObject = currentObject; if (isDoubleClick) { OnItemDoubleClick(this,null); } } else { _LastDataGridRow = null; _LastDataGridCell = null; _LastDataGridColumn = null; _LastObject = null; } _LastClick = clickTime; } private bool GetDataGridCellByPosition(Point pt, out DataGridRow dataGridRow, out DataGridColumn dataGridColumn, out DataGridCell dataGridCell, out object dataGridObject) { var elements = VisualTreeHelper.FindElementsInHostCoordinates(pt, this); dataGridRow = null; dataGridCell = null; dataGridColumn = null; dataGridObject = null; if (null == elements || elements.Count() == 0) { return false; } var rowQuery = from gridRow in elements where gridRow is DataGridRow select gridRow as DataGridRow; dataGridRow = rowQuery.FirstOrDefault(); if (dataGridRow == null) { return false; } dataGridObject = dataGridRow.DataContext; var cellQuery = from gridCell in elements where gridCell is DataGridCell select gridCell as DataGridCell; dataGridCell = cellQuery.FirstOrDefault(); if (dataGridCell != null) { dataGridColumn = DataGridColumn.GetColumnContainingElement(dataGridCell); } //If we've got the row, return true - sometimes the Column, DataContext could be null return dataGridRow != null; } private void OnItemDoubleClick(object sender,RoutedEventArgs e) { OnCommit(this, e); } protected override void OnKeyDown(KeyEventArgs e) { HandleKeyDown(e); if (!e.Handled) base.OnKeyDown(e); } /// /// Process a key down event. /// /// The key event arguments object. public void HandleKeyDown(KeyEventArgs e) { switch (e.Key) { case Key.Enter: OnCommit(this, e); e.Handled = true; break; case Key.Escape: OnCancel(this, e); e.Handled = true; break; default: break; } } /// /// Fires the Commit event. /// /// The source object. /// The event data. private void OnCommit(object sender, RoutedEventArgs e) { RoutedEventHandler handler = Commit; if (handler != null) { handler(sender, e); } } /// /// Fires the Cancel event. /// /// The source object. /// The event data. private void OnCancel(object sender, RoutedEventArgs e) { RoutedEventHandler handler = Cancel; if (handler != null) { handler(sender, e); } } /// /// Initializes a new instance of a DataGridAutomationPeer. /// /// Returns a new DataGridAutomationPeer. public AutomationPeer CreateAutomationPeer() { return new DataGridAutomationPeer(this); } } }