我有一个DataGrid
,其中SelectedItem
绑定到VM Selected属性。我有一个搜索控件,可以执行查找和SelectedItem
更改DataGrid
(并滚动到视图中)。 WPF 4.0和DataGrid
SelectionUnit="FullRow"
。
我的问题在于焦点。 DataGrid
获得焦点(通过附加属性/绑定)但您不能使用 Up , Down , Page Up , Page Down 更改行的键(SelectedItem
)。如果我再次选中,则会显示第一行显示的第一个单元格,它会更改SelectedItem
。
最重要的是,当DataGridCell
获得焦点时,如何为SelectedItem
的{{1}}提供键盘焦点?
有很多DataGrid
/ DataGrid
个问题并且已经尝试了一些事情。谢谢你的帮助。
答案 0 :(得分:7)
您需要为新选择的行提供逻辑焦点。选择新项目后,请尝试将此SetFocus
来电替换为:
var selectedRow = (DataGridRow)dataGrid1.ItemContainerGenerator.ContainerFromIndex(dataGrid1.SelectedIndex);
FocusManager.SetIsFocusScope(selectedRow, true);
FocusManager.SetFocusedElement(selectedRow, selectedRow);
答案 1 :(得分:0)
此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")))
}
})
答案 2 :(得分:0)
由于某些原因,FocusManager解决方案对我不起作用。我还需要一个更通用的apporach。所以这就是我想出的:
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();
}
}
}
并称之为:
MyDataGrid.IsKeyboardFocusWithinChanged += (sender, e) =>
{
if ((bool)e.NewValue == true)
{
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Loaded, new Action(() =>
{
MyDataGrid.RestoreFocus(scrollIntoView: true);
}));
}
};