Search code examples
c#wpfwpfdatagrid

How to override automate creation of data grid column header?


since WPF creates column headers automatically based on which class is holding data, I'd like to ask if there is a possibility to override this process?

For example, having this class

public class Report
{
    public string Value { get; set; }
    public int Title { get; set; }
}

I will receive 2 columns - | Value | Title |

As I see it now, WPF creates those columns headers by getting the name of property and "pastes" plain output of what it gets

something like this?

nameof(property);

The goal I want to achieve is to create a custom attribute for the property like

[Header("Price in €")]
public string Value { get; set}

and let WPF create column header based on that attribute, so my columns would be like this -

| Price in € | Title |

My question is how to override this?


Solution

  • You can create a simple Behavior for that.

    I will use the ComponentModel.DescriptionAttribute in this example, but you can of course use any custom attribute.

    using System.ComponentModel;
    using System.Windows.Interactivity;
    
    class ExtendendHeadersBehavior : Behavior<DataGrid>
    {
        protected override void OnAttached()
        {
            AssociatedObject.AutoGeneratingColumn += AssociatedObject_AutoGeneratingColumn;
        }
    
        protected override void OnDetaching()
        {
            AssociatedObject.AutoGeneratingColumn -= AssociatedObject_AutoGeneratingColumn;
        }
    
        private void AssociatedObject_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            if (e.PropertyDescriptor is PropertyDescriptor desc)
            {
                string header = desc.Attributes.OfType<DescriptionAttribute>()
                    .FirstOrDefault()?.Description;
    
                if (!string.IsNullOrEmpty(header))
                {
                    e.Column.Header = header;
                }
            }      
        }
    }
    

    Usage:

    <DataGrid>
        <i:Interaction.Behaviors>
            <b:ExtendendHeadersBehavior/>
        </i:Interaction.Behaviors>
    </DataGrid>
    

    The namespaces are:

    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:b="clr-namespace:YourAppNamespace"