Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF DataGrid列标题鼠标事件_C#_Wpf - Fatal编程技术网

C# WPF DataGrid列标题鼠标事件

C# WPF DataGrid列标题鼠标事件,c#,wpf,C#,Wpf,我试图通过在派生控件中添加一些方法和属性来扩展标准的DataGrid功能: public class ExtendedGrid : DataGrid { ... } 然而,我仍然不清楚如何处理头部的鼠标事件。由于DataGridColumnHeader不是可视化树的一部分(如果我有错误,请纠正我),为MouseeEvent设置事件处理程序的唯一方法是对其应用样式() 由于我正在扩展数据网格,我希望在代码中保留实现,而不添加任何XAML,我认为它在代码可读性方面是不一致的。因此,我编写了

我试图通过在派生控件中添加一些方法和属性来扩展标准的
DataGrid
功能:

public class ExtendedGrid : DataGrid
{
    ...
}
然而,我仍然不清楚如何处理头部的鼠标事件。由于
DataGridColumnHeader
不是可视化树的一部分(如果我有错误,请纠正我),为
MouseeEvent
设置事件处理程序的唯一方法是对其应用样式()

由于我正在扩展
数据网格
,我希望在代码中保留实现,而不添加任何XAML,我认为它在代码可读性方面是不一致的。因此,我编写了以下代码:

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;
    }
}
此代码在
自动生成列
上被调用,无法正常工作(例如根本无法正常工作)。即使会,它也会对设置标题样式施加限制


在my
ExtendedGrid
中,有没有一种方法可以在不使用任何XAML的情况下处理
DataGridColumnHeader
鼠标事件?或者XAML样式无论如何都比搜索解决方法(可能是过度复杂的事情)要好?

DataGridColumnHeader
当然是可视化树的一部分。
DataGridColumn
及其子体不是可视化树的一部分,因为它们用作实际渲染的
cellmetplate
HeaderTemplate
的数据对象

请注意,由于
DataGridColumnHeader
扩展了
ButtonBase
,因此还可以执行分配给
DataGridColumnHeader.Command的
ICommand

如果要为某个事件执行相同的事件处理程序,例如,为每个
DataGridColumnHeader
单击
,例如,为了执行基于列的排序,则可以直接在
DataGrid
上注册路由事件的处理程序:

<DataGrid DataGridColumnHeader.Click="SortColumn_OnClick" />
如果要查找一列或多列的特定
DataGridColumnHeader
,请遍历可视化树以找到它们。
您可以通过处理
DataGrid.Loaded
事件来获取特定列的
DataGridColumnHeader

main window.xaml

<DataGrid Loaded="DataGrid_OnLoaded" />

MainWindow.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;
}
private void DataGrid\u已加载(对象发送方,路由目标)
{
var dataGrid=发送方作为dataGrid;
foreach(dataGrid.Columns中的DataGridColumn DataGridColumn)
{
if(TryFindColumnHeader(dataGrid,dataGridColumn.DisplayIndex,out DataGridColumnHeader columnHeader))
{
columnHeader.Click+=(发送者,参数)=>MessageBox.Show($“Column#{columnHeader.DisplayIndex}标题已单击”);
}
}
}
公共布尔tryfind列标题(
DependencyObject数据网格,
int列索引,
输出DataGridColumnHeader(DataGridColumnHeader)
{
dataGridColumnHeader=null;
for(var childIndex=0;childIndex
可能您正在查找事件
GridViewColumnHeader。单击
?不,我正在查找MouseDown事件,仅此而已。顺便问一下,
DataGrid
是否在其代码中的某个地方以相同的方式初始化这些
DataGridColumnHeader
s,因此,可以使用与您的答案类似的方法扩展此方法。
DataGrid
包含一个
DataGridColumnHeadersPresenter
,它生成
DataGridColumnHeader
元素作为其子元素。没有可以覆盖的方法,例如,用于处理与此流程相关的事件。这是内部的。通常不需要直接访问
DataGridColumnHeader
容器。若要附加命令或事件处理程序,请使用样式或事件触发器;若要自定义其外观,请使用模板。I样式或事件触发器不是选项,您必须自己挖掘
DataGridColumnHeader
元素。您可以创建附加行为,并通过附加属性公开此
DataGridColumnHeader
项,或扩展
DataGrid
并添加相应的逻辑或创建扩展方法。这是使其可重用的唯一方法。请注意,必须加载
DataGrid
,才能访问
DataGridColumnHeader
项。
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;
}