[英]C# WPF KeyDown highlight + selected last row in datagrid
I'm working on application where user can add products to a datagrid, with simple informations like product name and price, and after that I would like to for example press F4 key on my keyboard and I would like to focus on last item in datagrid, that means select it and HIGHLIGHT that item! 我正在开发一个应用程序,用户可以使用简单的信息(如产品名称和价格)将产品添加到数据网格中,然后我想例如按键盘上的F4键,然后我要关注数据网格中的最后一项,这意味着选择它并突出显示该项目!
So guys how could I achieve that, I've tried few solutions like setting selected index to my datagrid and smth like that, but it is not working 所以,伙计们,我该如何实现这一目标,我尝试了一些解决方案,例如将选择的索引设置为我的数据网格和类似的方法,但是它无法正常工作
Thanks guys, Cheers 谢谢大家,干杯
Programmatically highlighting a row or cell in a DataGrid
is a bit more complicated than just setting the SelectedIndex
or SelectedItem
property. 以编程方式突出显示DataGrid
的行或单元格比仅设置SelectedIndex
或SelectedItem
属性要复杂一些。
It is however possible to select and focus a row in code and get the same behaviour as when using the mouse by accessing the visual user interface elements of the DataGrid
control and calling the UIElement.Focus()
method on a particular DataGridCell
object as described in the following blog post. 但是,可以通过访问DataGrid
控件的可视用户界面元素并在特定的DataGridCell
对象上调用UIElement.Focus()
方法来选择并集中代码中的一行,并获得与使用鼠标时相同的行为,如下所述。以下博客文章。
How to programmatically select and focus a row or cell in a DataGrid in WPF: https://blog.magnusmontin.net/2013/11/08/how-to-programmatically-select-and-focus-a-row-or-cell-in-a-datagrid-in-wpf/ 如何在WPF中以编程方式选择和突出显示DataGrid中的行或单元格: https : //blog.magnusmontin.net/2013/11/08/how-to-programmatically-select-and-focus-a-row-or- WPF中的数据网格中的单元格/
Here is an example: 这是一个例子:
public partial class MainWindow : Window
{
public MainWindow
{
InitializeComponent();
this.PreviewKeyDown += (s, e) =>
{
if(e.Key == Key.F4)
SelectRowByIndex(dataGridProducts, dataGridProducts.Items.Count - 1);
};
//populate DataGrid etc...
}
private static void SelectRowByIndex(DataGrid dataGrid, int rowIndex)
{
if (!dataGrid.SelectionUnit.Equals(DataGridSelectionUnit.FullRow))
throw new ArgumentException("The SelectionUnit of the DataGrid must be set to FullRow.");
if (rowIndex < 0 || rowIndex > (dataGrid.Items.Count - 1))
throw new ArgumentException(string.Format("{0} is an invalid row index.", rowIndex));
dataGrid.SelectedItems.Clear();
object item = dataGrid.Items[rowIndex];
dataGrid.SelectedItem = item;
DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
if (row == null)
{
/* bring the data item (Product object) into view
* in case it has been virtualized away */
dataGrid.ScrollIntoView(item);
row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
}
if (row != null)
{
DataGridCell cell = GetCell(dataGrid, row, 0);
if (cell != null)
cell.Focus();
}
}
private static DataGridCell GetCell(DataGrid dataGrid, DataGridRow rowContainer, int column)
{
if (rowContainer != null)
{
System.Windows.Controls.Primitives.DataGridCellsPresenter presenter
= FindVisualChild<System.Windows.Controls.Primitives.DataGridCellsPresenter>(rowContainer);
if (presenter == null)
{
/* if the row has been virtualized away, call its ApplyTemplate() method
* to build its visual tree in order for the DataGridCellsPresenter
* and the DataGridCells to be created */
rowContainer.ApplyTemplate();
presenter = FindVisualChild<System.Windows.Controls.Primitives.DataGridCellsPresenter>(rowContainer);
}
if (presenter != null)
{
DataGridCell cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
if (cell == null)
{
/* bring the column into view
* in case it has been virtualized away */
dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[column]);
cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
}
return cell;
}
}
return null;
}
private static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T)
return (T)child;
else
{
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}
}
You can use an InputBinding to recognize the pressed F4 Key. 您可以使用InputBinding识别按下的F4键。
<Window.InputBindings>
<KeyBinding Key="F4"
Command="{Binding SelectLastItemCommand}" />
</Window.InputBindings>
You can have a look here for how to select the item: WPF Binding SelectedItem in DataGrid 您可以在此处查看如何选择项目: DataGrid中的WPF Binding SelectedItem
Where does your problem lie? 你的问题在哪里? With handling the button event or highlighting the row? 处理按钮事件还是突出显示行? It seems like its the latter, so have a look at this: https://www.codeproject.com/Tips/773382/Row-Highlighting-in-WPF-Grids 似乎是后者,因此请看一下: https : //www.codeproject.com/Tips/773382/Row-Highlighting-in-WPF-Grids
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.