我不需要单元格之间的焦点导航。我尝试在单元格样式中设置 Focusable="False" 并调整该行的 focusvisualstyle,但在这种情况下选择失败。
2 回答
是的,您需要将Selection Unit
for DataGrid 设置为FullRow
并borderThickness to 0
使用FocusVisualStyle to null
.
<DataGrid SelectionUnit="FullRow">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
</Style>
</DataGrid.CellStyle>
<!-- ... -->
</DataGrid>
更新
上面提到的 xaml 是最好的,你可以使用仅 xaml 的方法,但如果你也想处理表格,那么你必须去后面的代码。这就是我实现它的方式 -
<DataGrid x:Name="dg" ItemsSource="{Binding Objects}" SelectionUnit="FullRow">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<EventSetter Event="PreviewKeyDown" Handler="dg_PreviewKeyDown"/>
</Style>
</DataGrid.CellStyle>
</DataGrid>
后面的代码(我在这里做的是,如果用户按下右键或左键只需处理它们以停止从一个单元格到另一个单元格的导航,如果用户按下 Tab 键,焦点应该转到下一行(如果可用)而不是移动到下一个单元格) -
private void dg_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Left || e.Key == Key.Right)
e.Handled = true;
else if (e.Key == Key.Tab)
{
DataGridRow a = UtilityFunctions.FindParent<DataGridRow>(sender as DependencyObject);
DataGridRow nextDataGridRow =(DataGridRow)dg.ItemContainerGenerator
.ContainerFromIndex(a.GetIndex() + 1);
if (nextDataGridRow != null)
{
dg.SelectedIndex = a.GetIndex() + 1;
DataGridCell cell = UtilityFunctions.FindChild<DataGridCell>
(nextDataGridRow as DependencyObject, "");
cell.Focus();
}
e.Handled = true;
}
}
在上面的代码中,我使用了一些实用程序函数来遍历可视树以在可视树中找到必要的父项或子项。供您参考,代码如下 -
public class UtilityFunctions
{
public static Parent FindParent<Parent>(DependencyObject child)
where Parent : DependencyObject
{
DependencyObject parentObject = child;
//We are not dealing with Visual, so either we need to fnd parent or
//get Visual to get parent from Parent Heirarchy.
while (!((parentObject is System.Windows.Media.Visual) || (parentObject is System.Windows.Media.Media3D.Visual3D)))
{
if (parentObject is Parent || parentObject == null)
{
return parentObject as Parent;
}
else
{
parentObject = (parentObject as FrameworkContentElement).Parent;
}
}
//We have not found parent yet , and we have now visual to work with.
parentObject = VisualTreeHelper.GetParent(parentObject);
//check if the parent matches the type we're looking for
if (parentObject is Parent || parentObject == null)
{
return parentObject as Parent;
}
else
{
//use recursion to proceed with next level
return FindParent<Parent>(parentObject);
}
}
public static T FindChild<T>(DependencyObject parent, string childName)
where T : DependencyObject
{
// Confirm parent is valid.
if (parent == null) return null;
T foundChild = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
// If the child is not of the request child type child
T childType = child as T;
if (childType == null)
{
// recursively drill down the tree
foundChild = FindChild<T>(child, childName);
// If the child is found, break so we do not overwrite the found child.
if (foundChild != null) break;
}
else if (!string.IsNullOrEmpty(childName))
{
var frameworkElement = child as FrameworkElement;
// If the child's name is set for search
if (frameworkElement != null && frameworkElement.Name == childName)
{
// if the child's name is of the request name
foundChild = (T)child;
break;
}
}
else
{
// child element found.
foundChild = (T)child;
break;
}
}
return foundChild;
}
}
要删除单元格之间的焦点导航:使用以下代码