如何通过列名获取列索引?

5

我有一个包含几列的数据网格 -

该网格的标题是超链接,我正在运行时设置其值,如下所示 -

string strQ1 = "<a href='somePage.aspx?ID=1'>gfgytyty<a>";
dtGrid.Columns[0].Header = strq1;

string strQ2 = "<a href='somePage.aspx?ID=2'>yhtryrtuyu<a>";
dtGrid.Columns[1].Header = strq2;

and so on...

现在它正常工作。 假设我想通过列名获取datagrid的特定列的索引,但我无法获取它。 我尝试过


请注意,此处保留了HTML标签。
int  colIndex = dtGrid.Columns.IndexOf(dtGrid.Columns[strQ2]);

这段代码本应返回columnIndex的值为1,但却返回了-1。

同时,dtGrid.Columns[strQ2]给我的是null值。

我在这里做错了什么?


WPF DataGrid 还是 WinForms DataGridView? - Tim Schmelter
这个代码 - dtGrid.Columns[strQ2] 是不是指向一个有效的DataGridColumn对象,请验证一下,这可能是一个问题。在你的情况中,我看到你将strq2分配为标题,但在IndexOf调用中使用了strQ2。 - Mrinal Kamboj
@MrinalKamboj 是的,你说得对!! dtGrid.Columns[strQ2] 返回 null。你能告诉我解决方法吗? - Microsoft DN
你确定它是winforms datagrid吗?它没有Columns属性。但是DataGridViewColumn没有Header属性,只有HeaderText属性。也许你指的是wpf DataGrid,它的列有一个Header属性。请不要混淆在一起。 - Tim Schmelter
在您的原始解决方案中,您可以尝试将dtGrid.Columns[strQ2]强制转换为DataGridColumn并检查,因为您正在使用的内容将提供一个对象类型,该类型在Equals方法中进行引用比较。 - Mrinal Kamboj
我的第一个、现已删除的回答是不正确的:“DataGridViewColumnCollection.IndexOf委托给ArrayList.IndexOf,后者使用Object.Equals来比较对象。在这种情况下,您比较的是没有有效覆盖Equals方法的DataGridViewColumns。因此,只有引用被比较。”这与问题无关,因为OP正在搜索刚从同一网格中获取的列,所以它是相同的引用。实际上,问题的原因是DataGridViewColumnCollection.Item索引器属性使用的是列的名称而不是标题文本。 - Tim Schmelter
2个回答

10
你可以使用LINQ FirstOrDefault先获取对象,然后再使用.IndexOf(object)方法:
var targetColumn = dtGrid.Columns.FirstOrDefault(c => c.Header == strQ2);
var index = dtGrid.Columns.IndexOf(targetColumn);

如果我想检查 c.Header 是否包含一个值,该怎么办? - Si8

8
这里提供另一种使用 List.FindIndex 的方法:

int index = dtGrid.Columns.ToList().FindIndex(c => c.Header  == strQ2);

如果不是 WPF 的 DataGrid(由于它具有 Header 属性,看起来似乎不是),而是一个没有实现泛型集合类型的 winforms DataGridView,你需要在使用 LINQ 方法之前将其转换:

var columnList = dtGrid.Columns.Cast<DataGridViewColumn>().ToList();
int index = columnList.FindIndex(c => c.HeaderText  == strQ2);

这将是一个O(n)的解决方案,相比之下,Linq查询更可取。 - Mrinal Kamboj
2
@MrinalKamboj:被接受的方法需要两次枚举列集合。然而,由于没有成千上万的列,这不是问题。 - Tim Schmelter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接