wpf 当 DataGrid 接收键盘焦点时,将焦点放在 SelectedItem 的 DataGridCell 上
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17117281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Focus on DataGridCell for SelectedItem when DataGrid Receives Keyboard Focus
提问by KornMuffin
I have a DataGridwhere the SelectedItemis bound to a VM Selected property. I have a search control that will do a find and the SelectedItemof the DataGridchanges (and scrolls into view). WPF 4.0 and DataGridSelectionUnit="FullRow".
我有一个DataGrid在SelectedItem绑定到一个VM Selected属性。我有一个搜索控制,将做一个查找和SelectedItem的DataGrid变化(和滚动到视图)。WPF 4.0 和DataGridSelectionUnit="FullRow".
My problem is with the focus. The DataGridreceives focus (via attached property / binding) but you can't use the Up, Down, Page Up, Page Downkeys to change rows (SelectedItem). If I tab again, the first cell of the first row displayed is selected which changes the SelectedItem.
我的问题是焦点。的DataGrid(/经由附加属性结合)接收焦点但不能使用Up,Down,Page Up,Page Down键改变行(SelectedItem)。如果我再次使用 Tab 键,则会选择显示的第一行的第一个单元格,这会更改SelectedItem.
Bottom line, how can I give keyboard focus to the DataGridCellfor the SelectedItemwhen the DataGridreceives focus?
最重要的DataGridCell是,SelectedItem当DataGrid接收到焦点时,如何将键盘焦点放在 ?
There are so many DataGrid/ Focusquestions and tried a few things already. Thanks for your help.
有很多DataGrid/Focus问题,并且已经尝试了一些事情。谢谢你的帮助。
采纳答案by Richard E
You need to give the newly selected row logical focus. After selecting the new item try replacing your SetFocuscall with this:
您需要为新选择的行赋予逻辑焦点。选择新项目后,请尝试用以下内容替换您的SetFocus电话:
var selectedRow = (DataGridRow)dataGrid1.ItemContainerGenerator.ContainerFromIndex(dataGrid1.SelectedIndex);
FocusManager.SetIsFocusScope(selectedRow, true);
FocusManager.SetFocusedElement(selectedRow, selectedRow);
回答by W1M0R
This PowerShell snippet worked for me:
这个 PowerShell 片段对我有用:
$dataGrid = ...
$dataGrid.add_GotKeyboardFocus({
param($Sender,$EventArgs)
if ($EventArgs.OldFocus -isnot [System.Windows.Controls.DataGridCell) {
$row = $dataGrid.ItemContainerGenerator.ContainerFromIndex($dataGrid.SelectedIndex)
$row.MoveFocus((New-Object System.Windows.Input.TraversalRequest("Next")))
}
})
回答by Tim Pohlmann
The FocusManager solution didn't work for me for some reason. Also I required a more general apporach. So here is, what I came up with:
由于某种原因,FocusManager 解决方案对我不起作用。我还需要一个更一般的方法。所以这是我想出的:
using System.Windows.Controls;
public static void RestoreFocus(this DataGrid dataGrid,
int column = 0, bool scrollIntoView = false)
{
if (dataGrid.IsKeyboardFocusWithin && dataGrid.SelectedItem != null)
{
// make sure everything is up to date
dataGrid.UpdateLayout();
if (scrollIntoView)
{
dataGrid.ScrollIntoView(dataGrid.SelectedItem);
}
var cellcontent = dataGrid.Columns[column].GetCellContent(dataGrid.SelectedItem);
var cell = cellcontent?.Parent as DataGridCell;
if (cell != null)
{
cell.Focus();
}
}
}
And call it like this:
并这样称呼它:
MyDataGrid.IsKeyboardFocusWithinChanged += (sender, e) =>
{
if ((bool)e.NewValue == true)
{
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Loaded, new Action(() =>
{
MyDataGrid.RestoreFocus(scrollIntoView: true);
}));
}
};

