[英]WPF DataGrid column header mouse events
I'm trying to extend standard DataGrid
functionality by adding some methods and properties into a derived control:我正在尝试通过将一些方法和属性添加到派生控件中来扩展标准
DataGrid
功能:
public class ExtendedGrid : DataGrid
{
...
}
However, handling mouse events of the headers is still unclear to me.但是,我仍然不清楚处理标题的鼠标事件。 Since
DataGridColumnHeader
is not a part of the visual tree (correct me if I mistake), and the only way to set an event handler to the MouseEvent
is to apply style on it ( How do I capture "Click" events on a DataGrid column headers ).由于
DataGridColumnHeader
不是可视树的一部分(如果我错了,请纠正我),并且将事件处理程序设置为MouseEvent
的唯一方法是在其上应用样式( 如何在 DataGrid 列标题上捕获“单击”事件)。
Since I'm extending the DataGrid
, I'd like to keep implementation in code, without adding any XAML, in my opiinion it's inconsistent in terms of code readability.由于我正在扩展
DataGrid
,我想在代码中保留实现,而不添加任何 XAML,在我看来,它在代码可读性方面是不一致的。 Therefore, I wrote the following code:因此,我编写了以下代码:
private void InitializeStyles()
{
Style headerStyle = new Style(typeof(DataGridColumnHeader));
headerStyle.Setters.Add(new EventSetter(MouseDownEvent, new MouseButtonEventHandler(OnColumnHeaderMouseDown)));
foreach(var column in Columns)
{
column.HeaderStyle = headerStyle;
}
}
This code is called on AutoGeneratedColumns
and doesn't work well (eg at all).此代码在
AutoGeneratedColumns
上调用,但效果不佳(例如,根本没有)。 Even if it would, it would impose limitations on setting styles on headers.即使这样,它也会对在标头上设置 styles 施加限制。
Is there a way to handle DataGridColumnHeader
mouse events in my ExtendedGrid
without any XAML?有没有办法在没有任何 XAML 的情况下处理我的
ExtendedGrid
中的DataGridColumnHeader
鼠标事件? Or XAML styles is anyway better than search of workarounds (and probably overcomplicationg things)?或者 XAML styles 无论如何都比寻找解决方法(并且可能过于复杂的事情)更好?
DataGridColumnHeader
is of course part of the visual tree. DataGridColumnHeader
当然是可视化树的一部分。 It's the DataGridColumn
and its descendants that are not part of the visual tree as they serve as data objects for the actual rendered CellTemplate
or HeaderTemplate
. DataGridColumn
及其后代不属于可视化树,因为它们充当实际呈现的CellTemplate
或HeaderTemplate
的数据对象。
Note that since DataGridColumnHeader
extends ButtonBase
, you can also execute an ICommand
that is assigned to DataGridColumnHeader.Command
.请注意,由于
DataGridColumnHeader
扩展了ButtonBase
,您还可以执行分配给DataGridColumnHeader.Command
的ICommand
。
If you want to execute the same event handler for a certain event eg, Click
for each DataGridColumnHeader
eg, in order to execute a column based sort, then you can simply register a handler for the routed event directly on the DataGrid
:如果您想为某个事件执行相同的事件处理程序,例如,
Click
每个DataGridColumnHeader
,例如,为了执行基于列的排序,那么您可以直接在DataGrid
上为路由事件注册一个处理程序:
<DataGrid DataGridColumnHeader.Click="SortColumn_OnClick" />
or when using a Style
set the DataGrid.ColumnHeaderStyle
:或者当使用
Style
设置DataGrid.ColumnHeaderStyle
:
<DataGrid>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<EventSetter Event="Click"
Handler="SortColumn_OnClick" />
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
If you are looking for a specific DataGridColumnHeader
of a column or columns, then traverse the visual tree to find them.如果您正在寻找一列或多列的特定
DataGridColumnHeader
,则遍历可视化树以查找它们。
You can get the DataGridColumnHeader
of a certain column by handling the DataGrid.Loaded
event:您可以通过处理
DataGrid.Loaded
事件来获取某一列的DataGridColumnHeader
:
MainWindow.xaml主窗口.xaml
<DataGrid Loaded="DataGrid_OnLoaded" />
MainWindow.xaml.cs主窗口.xaml.cs
private void DataGrid_OnLoaded(object sender, RoutedEventArgs e)
{
var dataGrid = sender as DataGrid;
foreach (DataGridColumn dataGridColumn in dataGrid.Columns)
{
if (TryFindColumnHeader(dataGrid, dataGridColumn.DisplayIndex, out DataGridColumnHeader columnHeader))
{
columnHeader.Click += (sender, args) => MessageBox.Show($"Column #{columnHeader.DisplayIndex} Header clicked");
}
}
}
public bool TryFindColumnHeader(
DependencyObject dataGrid,
int columnIndex,
out DataGridColumnHeader dataGridColumnHeader)
{
dataGridColumnHeader = null;
for (var childIndex = 0; childIndex < VisualTreeHelper.GetChildrenCount(dataGrid); childIndex++)
{
DependencyObject childElement = VisualTreeHelper.GetChild(dataGrid, childIndex);
if (childElement is DataGridColumnHeader columnHeader && columnHeader.DisplayIndex.Equals(columnIndex))
{
dataGridColumnHeader = columnHeader;
return true;
}
if (TryFindColumnHeader(childElement, columnIndex, out dataGridColumnHeader))
{
return true;
}
}
return false;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.