简体   繁体   English

如何捕获 DataGrid 列标题上的“单击”事件

[英]How do I capture “Click” events on a DataGrid column headers

It appears that the DataGrid that comes with .NET 4 does not contain an event for both column and row header clicks. .NET 4 附带的DataGrid似乎不包含列和行 header 点击的事件。 I want to receive events for the column header click as I want to provide my own sorting behaviour and turn off the default sorting, this is because my view-model is a paginated model that will only display 25/50/100 rows at a time, the default sorting will of-course sort the current page only.我想接收 header 列的事件单击,因为我想提供自己的排序行为并关闭默认排序,这是因为我的视图模型是分页 model 一次仅显示 25/50/100 行,默认排序当然只会对当前页面进行排序。

Now I could create a new DataGridColumnHeader style which contains a clickable element and and set ColumnHeaderStyle , though this just seems like a pain as I'll have trouble figuring out things like which column it was that got clicked etc.现在我可以创建一个新的DataGridColumnHeader样式,其中包含一个可点击的元素并设置ColumnHeaderStyle ,尽管这看起来很痛苦,因为我很难弄清楚它是被点击的列等。

Anyone else come up against this and solved it?还有其他人反对这个并解决了吗?

The headers are just buttons.标题只是按钮。 Like any button, you can register to the Click event to capture those clicks.像任何按钮一样,您可以注册到Click事件以捕获这些点击。 Just set a style targeting DataGridColumnHeader and add a Click event handler.只需设置针对DataGridColumnHeader的样式并添加Click事件处理程序。 Then within the handler, you have access to the header directly via the sender .然后在处理程序中,您可以通过sender直接访问 header 。 You could then get the Column associated with that header and other information associated with it.然后,您可以获得与该 header 关联的Column以及与之关联的其他信息。

<DataGrid>
    <DataGrid.Resources>
        <Style TargetType="DataGridColumnHeader">
            <EventSetter Event="Click" Handler="columnHeader_Click" />
        </Style>
    </DataGrid.Resources>
</DataGrid>

Then in the code:然后在代码中:

private void columnHeader_Click(object sender, RoutedEventArgs e)
{
    var columnHeader = sender as DataGridColumnHeader;
    if (columnHeader != null)
    {
        // do stuff
    }
}

Looking further into the DataGrid , I noticed that there's a ColumnHeaderStyle property.进一步查看DataGrid ,我注意到有一个ColumnHeaderStyle属性。 I think it would be a better idea to apply the style through this property instead.我认为通过此属性应用样式会更好。

<DataGrid>
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <EventSetter Event="Click" Handler="columnHeader_Click" />
        </Style>
    </DataGrid.ColumnHeaderStyle>
</DataGrid>

It is also possible to do this programmatically :也可以以编程方式执行此操作:

using System.Windows.Controls.Primitives;

...

public TestWindow()
{
  if (TestDataGrid.ColumnHeaderStyle == null)
  {
    TestDataGrid.ColumnHeaderStyle = new Style(typeof(DataGridColumnHeader));
  }
  TestDataGrid.ColumnHeaderStyle.Setters.Add(new EventSetter(ButtonBase.ClickEvent,
       new RoutedEventHandler(TestDataGrid_HeaderRowClick)));
}


private void TestDataGrid_HeaderRowClick(object sender, RoutedEventArgs e)
{
  ...
}

Here the method "TestDataGrid_HeaderRowClick" is called, when the use clicks with the left mouse button into the header row.当用户用鼠标左键单击 header 行时,这里调用方法“TestDataGrid_HeaderRowClick”。

After struggling for quite a long time, I got this full resolution.经过很长时间的努力,我得到了这个完整的解决方案。

In FormMain.Designer.cs, add handler (the second one):在 FormMain.Designer.cs 中,添加处理程序(第二个):

    private void InitializeComponent()
    {
        ...
        this.TableOfBriefs.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.TableOfBriefs_CellContentClick);
        this.TableOfBriefs.ColumnHeaderMouseClick += new DataGridViewCellMouseEventHandler(this.TableOfBriefs_HeaderClick);

In Forman.cs, add the method:在 Forman.cs 中,添加方法:

    private readonly Dictionary<string, bool> _columnName2Orders = new Dictionary<string, bool>();
    private const bool IsAscendingWhenFirstClicked = false;
    private void TableOfBriefs_HeaderClick(object sender, DataGridViewCellMouseEventArgs e)
    {
        if (!(sender is DataGridView dataGrid))
            throw new ArgumentException(@$"{sender} is not a {typeof(DataGridView)}.");

        var column = dataGrid.Columns[e.ColumnIndex];
        var propertyInfo = typeof(CciSingleFileResultBrief).GetProperty(column.Name);
        if (propertyInfo == null)
            throw new ArgumentException($@"There is no property named {column.Name} found in class {typeof(CciSingleFileResultBrief)}.");

        if (!_columnName2Orders.ContainsKey(propertyInfo.Name))
            _columnName2Orders.Add(propertyInfo.Name, IsAscendingWhenFirstClicked);
        _columnName2Orders[propertyInfo.Name] = !_columnName2Orders[propertyInfo.Name];

        var isAscending = _columnName2Orders[propertyInfo.Name];
        var briefs = isAscending ? _briefs.OrderByDescending(i => propertyInfo.GetValue(i)).ToList()
                : _briefs.OrderBy(i => propertyInfo.GetValue(i)).ToList();
        TableOfBriefs.DataSource = briefs;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在UserControl中捕获MouseWheel事件? - How do I capture MouseWheel events in a UserControl? 如何更改DataGrid的列宽 - How do i change the column width of a DataGrid 如何从Android设备(响应程序)生成自定义MTP事件,并在Windows(启动程序)中捕获事件 - How do I generate custom MTP events from Android device (responder), and capture events in Windows (initiator) 如何在我的datagrid XAML中将列标题居中 - How do I center the column header in my datagrid XAML DataGrid列标题与数据不对齐 - DataGrid column headers not aligned with data 如何在单击列 header 的 DataGridView 中对 DataBound 列进行排序? - How do I sort a DataBound column in a DataGridView on a column header click? 我想启用我的 dataGrid 的特定列以在单击按钮时进行编辑 - I want to enable the a particular column of my dataGrid to edit on button click .NET 4.0 WPF,带有行和列标题的 DataGrid - .NET 4.0 WPF, DataGrid with Row and column headers WPF-如何绑定DataGrid,其中一列充当枢轴,其余部分形成行和列 - WPF - How do I bind DataGrid where a column act as pivot and rest form rows and columns 将应用程序与.NET挂钩,以捕获双击事件 - Hook application with .NET to capture double click events
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM