how to get column Index by column name?
Asked Answered
C

2

5

I have a datagrid having few columns-

The header of the grid is hyperlink and I am setting its value at runtime as follows-

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...

It is working properly. Now suppose I want to get index of a perticular column of datatgrid by its name but I am not able to get it. I tried

int  colIndex = dtGrid.Columns.IndexOf(dtGrid.Columns[strQ2]);

this should return 1 as columnIndex but it is returning -1,

Also, dtGrid.Columns[strQ2] giving me the null value.

what I am doing wrong here?

Cotsen answered 14/7, 2015 at 10:44 Comment(6)
wpf datagrid or winforms datagridview?Lavation
Is this - dtGrid.Columns[strQ2] leading to valid DataGridColumn object, please verify, that might be an issue. in your case i can see you are assigning strq2 as header but using strQ2 in the IndexOf callForedo
@MrinalKamboj Yes you are right!! dtGrid.Columns[strQ2] is giving null. Can you please tell the workaround.Cotsen
Are you sure that it's winforms datagrid? That has no Columns property. But a DataGridViewColumn has no Header but a HeaderText property. Maybe you mean wpf DataGrid which columns have a Header property. Please don't mix up all together.Lavation
In your original solution, can you try typecasting dtGrid.Columns[strQ2] to DataGridColumn and check, since what you are using will give an object type, which does the reference comparison in the Equals methodForedo
@MicrosoftDN: my first, now deleted answer wasn't correct: "DataGridViewColumnCollection.IndexOf delegates to ArrayList.IndexOf which uses Object.Equals to compare objects. In this case you compare DataGridViewColums which does not override Equals meaningfully. For that reason only references are compared." That has nothing to do with this issue since OP is searching a column that he has just taken from the same grid, so it's the same reference. Actually the reason for the issue is that the DataGridViewColumnCollection.Item-indexer property uses the name of the column not the header-text.Lavation
S
10

You could use LINQ FirstOrDefault to get the object first and only then use .IndexOf(object) :

var targetColumn = dtGrid.Columns.FirstOrDefault(c => c.Header == strQ2);
var index = dtGrid.Columns.IndexOf(targetColumn);
Santasantacruz answered 14/7, 2015 at 11:3 Comment(1)
what if I wanted to check if c.Header contains a value?Moonfish
L
8

Here's another approach using List.FindIndex:

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

If it's not the WPF DataGrid(which it seems to be due to the Header property) but a winforms DataGridView that doesn't implement a generic collection type, you need to cast it before you can use LINQ methods:

var columnList = dtGrid.Columns.Cast<DataGridViewColumn>().ToList();
int index = columnList.FindIndex(c => c.HeaderText  == strQ2);
Lavation answered 14/7, 2015 at 11:26 Comment(2)
This would be an O(n) solution, instead of that a Linq query will be preferableForedo
@MrinalKamboj: the accepted approach needs to enumerate the column collection twice. However, since there are not thousand columns that's not an issue.Lavation

© 2022 - 2024 — McMap. All rights reserved.