.net 我如何捕捉“信息”;点击";DataGrid列标题上的事件
NET 4附带的.net 我如何捕捉“信息”;点击";DataGrid列标题上的事件,.net,wpf,.net-4.0,.net,Wpf,.net 4.0,NET 4附带的DataGrid似乎不包含列标题和行标题单击事件。我想接收列标题单击的事件,因为我想提供自己的排序行为并关闭默认排序,这是因为我的视图模型是分页模型,一次只显示25/50/100行,默认排序当然只对当前页面进行排序 现在我可以创建一个新的DataGridColumnHeader样式,其中包含一个可单击的元素,并设置ColumnHeaderStyle,尽管这看起来很痛苦,因为我很难弄清楚单击的是哪个列等 还有谁碰到这个问题并解决了吗?标题只是按钮。与任何按钮一样,您可以注册到Cli
DataGrid
似乎不包含列标题和行标题单击事件。我想接收列标题单击的事件,因为我想提供自己的排序行为并关闭默认排序,这是因为我的视图模型是分页模型,一次只显示25/50/100行,默认排序当然只对当前页面进行排序
现在我可以创建一个新的DataGridColumnHeader
样式,其中包含一个可单击的元素,并设置ColumnHeaderStyle
,尽管这看起来很痛苦,因为我很难弄清楚单击的是哪个列等
还有谁碰到这个问题并解决了吗?标题只是按钮。与任何按钮一样,您可以注册到
Click
事件以捕获这些单击。只需设置样式定位DataGridColumnHeader
,并添加单击事件处理程序。然后,在处理程序中,您可以通过发送方
直接访问标头。然后可以获得与该标题相关联的列
,以及与之相关联的其他信息
然后在代码中:
private void columnHeader_Click(object sender, RoutedEventArgs e)
{
var columnHeader = sender as DataGridColumnHeader;
if (columnHeader != null)
{
// do stuff
}
}
进一步查看数据网格
,我注意到有一个属性。我认为通过这个属性应用样式会更好
也可以通过编程方式执行此操作:
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)
{
...
}
这里调用了“TestDataGrid\u HeaderRowClick”方法,当用户用鼠标左键点击标题行时。经过相当长时间的努力,我得到了这个完整的解决方案
在FormMain.Designer.cs中,添加处理程序(第二个):
在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;
}
private readonly Dictionary\u columnName2Orders=new Dictionary();
private const bool Isascentingwhenfirstclicked=false;
Briefs_HeaderClick的私有无效表(对象发送方,DataGridViewCellMouseEventArgs e)
{
如果(!(发送方为DataGridView dataGrid))
抛出新的ArgumentException(@$“{sender}不是{typeof(DataGridView)}.”);
var column=dataGrid.Columns[e.ColumnIndex];
var propertyInfo=typeof(CciSingleFileResultBrief).GetProperty(column.Name);
如果(propertyInfo==null)
抛出新ArgumentException($@“在类{typeof(CciSingleFileResultBrief)}中找不到名为{column.Name}的属性。”);
if(!\u columnName2Orders.ContainsKey(propertyInfo.Name))
_columnName2Orders.Add(propertyInfo.Name,在单击时显示);
_ColumnName2订单[propertyInfo.Name]=!\u ColumnName2订单[propertyInfo.Name];
var isAscending=_columnName2Orders[propertyInfo.Name];
var-briefs=isAscending?\u-briefs.OrderByDescending(i=>propertyInfo.GetValue(i)).ToList()
:_briefs.OrderBy(i=>propertyInfo.GetValue(i)).ToList();
TableOfBriefs.DataSource=简介;
}
非常感谢杰夫,我以前从未使用过EventSetter
,非常方便。我有一个后续问题,你知道当CanUserSortColumns=“False”
标题响应鼠标悬停并显示排序方向时,是否可能获得样式行为,或者我需要自己重新设置样式吗?@Brett:对不起,你能重新措辞吗?我不确定我是否理解你的要求。在我看来,当排序被禁用时,您想获取与这些标题相关联的模板吗?谢谢Jeff,很抱歉造成歧义。我想做的是提供我自己的排序逻辑,在您的帮助下,我现在已经实现了这一点,但是我当然必须将CanUserSortColumns
设置为False
,否则控件将尝试执行sort False,但是我希望在将光标移动到列标题上时具有良好的“悬停”效果,并且希望“向上/向下”箭头指示排序方向(尽管后者不太重要)。非常感谢你的帮助。@Brett:我很肯定你能,我只是不记得如何诚实。不过我会调查的。您可能想把它作为另一个问题发布。@Brett:请参阅我的更新。以防万一你还没注意到这一点。
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;
}