How to get DataGridColumnHeader from DataGridColumn?
Solution 1
The Header object of the DataGridColumn is actually the visible header of that column, whatever you set it to be. DataGridColumn is not part of the Visual Tree so there is not direct way to access the DataGridColumnHeader for it (we can't even be sure it exists yet). But you can do something like this to try and access it
DataGridColumnHeader headerObj = GetColumnHeaderFromColumn(column);
private DataGridColumnHeader GetColumnHeaderFromColumn(DataGridColumn column)
{
// dataGrid is the name of your DataGrid. In this case Name="dataGrid"
List<DataGridColumnHeader> columnHeaders = GetVisualChildCollection<DataGridColumnHeader>(dataGrid);
foreach (DataGridColumnHeader columnHeader in columnHeaders)
{
if (columnHeader.Column == column)
{
return columnHeader;
}
}
return null;
}
public List<T> GetVisualChildCollection<T>(object parent) where T : Visual
{
List<T> visualCollection = new List<T>();
GetVisualChildCollection(parent as DependencyObject, visualCollection);
return visualCollection;
}
private void GetVisualChildCollection<T>(DependencyObject parent, List<T> visualCollection) where T : Visual
{
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is T)
{
visualCollection.Add(child as T);
}
else if (child != null)
{
GetVisualChildCollection(child, visualCollection);
}
}
}
Solution 2
While Fredrik's answer provides a refactored approach with additional method that could potentially be reused in other parts of the code, I preferred to consolidate his methods in to one single method. There may also be some small performance gain because it can end the search as soon as it finds the header and it does not need to continue to search through all the children in the visual tree (this is most likely negligible for most cases).
private DataGridColumnHeader GetHeader(DataGridColumn column, DependencyObject reference)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(reference); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(reference, i);
DataGridColumnHeader colHeader = child as DataGridColumnHeader;
if ((colHeader != null) && (colHeader.Column == column))
{
return colHeader;
}
colHeader = GetHeader(column, child);
if (colHeader != null)
{
return colHeader;
}
}
return null;
}
And it is used like so:
DataGridColumnHeader colHeader = GetHeader(column, myDataGrid);
if (colHeader == null) { /* Not found */ }
![Gurucharan Balakuntla Maheshku](https://i.stack.imgur.com/F9g8g.jpg?s=256&g=1)
Gurucharan Balakuntla Maheshku
“My objective is to provide solutions which can change the way people think and have a great impact on them” Software Engineering and Technology leader with 14+ years of experience in the IT industry leading and managing mid-scale to large scale digital systems (as Project Management, Product Management, People Management) across cross-functional teams and delivering highly performant, scalable, and secure systems. Well-versed in managing geographically distributed diverse teams across startups, MNC's and Enterprises. Deep knowledge in web architecture and technologies to solve challenging and complex business problems. Vast experience in recruiting and growing a team, instilling the right culture, motivating and retaining the best talents. I have served in diverse domains like Digital Web Apps, eCommerce, Payments, Enterprise applications, CRM, etc. with strong product and project management abilities.
Updated on July 28, 2022Comments
-
Gurucharan Balakuntla Maheshku almost 2 years
My code is as follows:
void mainDataContextObj_CutSelectedColumnEvent(string columnId) { IList<DataGridColumn> columns = dg.Columns; for(int i=2; i<dg.Columns.Count; i++) { DataGridColumnHeader headerObj = dg.Columns[i].Header as DataGridColumnHeader; //This always returns headerObj as null!!! } }
I need
DataGridColumnHeader
from the column. Where am I going wrong? -
Konrad Morawski almost 13 yearsIt is not available in the
AutoGeneratedColumns
event (it can't find any headers yet, it returns null). It does work afterwards. So when exactly are these headers created?! -
Fredrik Hedblad almost 13 years@Vibo: Try the Loaded event for DataGrid
-
Konrad Morawski almost 13 yearsThanks! I tried it indeed, but the drawback was it was only fired in the beginning, but if you regenerated the columns of the DataGrid by assigning some other data source to its
DataContext
, it wasn't triggered again. I tried every possible event and I discovered thatLayoutUpdated
does the trick! -
Fredrik Hedblad almost 13 years@Vibo: Otherwise you can use the ItemContainerGenerator.StatusChanged event of DataGrid and compare the status to ContainersGenerated in the event handler
-
Konrad Morawski almost 13 yearsGood to know, thanks. Implementing it by
LayoutUpdated
was bit of a hack actually, because this event is fired quite often. Duct tape style, I just used aignoreLayoutUpdated
bool, setting it tofalse
in those parts of the app where it actually does something to headers so they need to be taken care of, and resetting totrue
before exiting the event. -
Tevin about 12 yearsDo you know if there's a way to do this in Silverlight? The DataGridColumnHeader has no Column property to compare against.