下面是我研究DataGrid的一点心得:
首先wpf datagrid binding,网上的列子多不胜数,这里就没必要再列举了,下面主要说的是datagrid的焦点控制。
默认的datagrid焦点控制都是由Tab控制的,按一下tab,焦点移动到下一个.但是其他的控件的焦点控制是用回车控制的,不是很统一。接下来我所要做的就是用回车键来控制datagrid的焦点移动。
先来说说我网上搜到的方法:
public class ExDataGrid:DataGrid { protected override void OnPreviewKeyDown(System.Windows.Input.KeyEventArgs e) { base.OnPreviewKeyDown(e); } }
override了OnPreviewKeyDown方法,使用基本控件的base.OnPreviewKeyDown,即回车控制焦点,但是有些问题,碰到表格里是datatemplate或者是combobox的时候,移动会有些问题。
网上也没有搜到其他方法,没办法只能求助于reflector看看微软是怎么实现tab焦点控制的。
UIElement focuseElement = Keyboard.FocusedElement as UIElement; FocusNavigationDirection focusNavigationDirection = flag2 ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next; TraversalRequest request = new TraversalRequest(focusNavigationDirection); request.Wrapped = true; focuseElement.MoveFocus(request)
不过可恶的是,除了wpf提供OnKeyDown可以override之外,其他方法都是private的,没办法只能照着他的思路,自己写一套了。
private void OnEnterKeyDown(System.Windows.Input.KeyEventArgs e) { _isMouseClick = false; DataGridCell currentCellContainer = null; if (this.CurrentCell.Column.Header!=null) { currentCellContainer = this.TryFindCell(this.CurrentCell); } else { currentCellContainer = this.CurrentCellContainer; } if (currentCellContainer != null) { bool isEditing = currentCellContainer.IsEditing = true; bool flag2 = (e.KeyboardDevice.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift; UIElement focuseElement = Keyboard.FocusedElement as UIElement; var myDataGridTextColumn = currentCellContainer.Column as MyDataGridTextColumn; ContentElement element2 = (focuseElement == null) ? (Keyboard.FocusedElement as ContentElement) : null; if (focuseElement != null || element2 != null) { e.Handled = true; FocusNavigationDirection focusNavigationDirection = flag2 ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next; TraversalRequest request = new TraversalRequest(focusNavigationDirection); request.Wrapped = false; if (focuseElement != null && focuseElement.MoveFocus(request) || element2 != null && element2.MoveFocus(request)) { _preUIElement = focuseElement; this.BringIntoView(); if (isEditing && flag2 && Keyboard.FocusedElement == currentCellContainer) currentCellContainer.MoveFocus(request); if (base.IsGrouping && isEditing) { DataGridCell cellForSelectAndEditOnFocusMove = this.GetCellForSelectAndEditOnFocusMove(); if (cellForSelectAndEditOnFocusMove != null && GetRowDataItem(cellForSelectAndEditOnFocusMove) == GetRowDataItem(currentCellContainer)) { DataGridCell cell3=this.TryFindCell(GetRowDataItem(cellForSelectAndEditOnFocusMove),cellForSelectAndEditOnFocusMove.Column); if (cell3 == null) { base.UpdateLayout(); cell3 = this.TryFindCell(GetRowDataItem(cellForSelectAndEditOnFocusMove), cellForSelectAndEditOnFocusMove.Column); } if (cell3 != null && cell3 != cellForSelectAndEditOnFocusMove) cell3.Focus(); } } this.SelectAndEditOnFocusMove(e, currentCellContainer, isEditing, false, true,focuseElement); } } } }
然后就可以override OnKeyDown
protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e) { if (this.Items.IndexOf(this.CurrentItem) == this.Items.Count - 1 && this.Columns.IndexOf(this.CurrentColumn) == this.Columns.Count - 1) { return; } if (e.Key == Key.Enter) OnEnterKeyDown(e); //base.OnKeyDown(e); }
这样基本的功能就完成了。