Setting ToolTip for DataGridView automatically created columns

2.3k views Asked by At

I would like to programatically set tooltips to automatically generated columns in a DataGridView. I was trying to use AutoGeneratingColumn event (http://msdn.microsoft.com/en-us/library/cc903950%28VS.95%29.aspx), but that in fact can only access DataGridColumn, not DataGridViewColumn, and the former doesn't have ToolTipText property.

Or if I could bind the ToolTips to a source that would also be great. The goal is to have the ability to manipulate/set tooltips in the same place where I set the columns for the underlying DataTable.

3

There are 3 answers

0
Adam Szabo On BEST ANSWER

I managed to solve it this way:

void payloadDataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    string tooltip = null;

    switch (e.Column.Header.ToString())
    {
        case "Column 1":
            tooltip = "Tooltip 1";
            break;
        case "Column 2":
            tooltip = "Tooltip 2";
            break;
    }

    if (tooltip != null)
    {
        var style = new Style(typeof(DataGridCell));
        style.Setters.Add(new Setter(ToolTipService.ToolTipProperty, tooltip));
        e.Column.CellStyle = style;
    }
}
0
Linus Proxy On

If you don't want to presuppose any types and want to rely on reflection to extract an attribute from your domain object to use as a tooltip, you can do it like so:

internal class SomeDomainObject
{
    [Description("Some tooltip text")]
    public string SomeProperty { get; set; } = string.Empty;
}

And we can use the ItemsSource enumerator to get the first element of the grid, which in turn will give us the domain object type to reflect upon. Here, I'm also setting the name of the property as a default tooltip using the null coalesce operator. (The cast to DataGrid should be safe since we know we're working with a DataGrid).

private void SomeGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    var enumerator = ((DataGrid)sender).ItemsSource.GetEnumerator();
    enumerator.MoveNext();
    var itemType = enumerator.Current.GetType();    
    var propInfo = itemType.GetProperty(e.PropertyName);
    var toolTip = propInfo?.GetCustomAttributes<DescriptionAttribute>()
        ?.ElementAtOrDefault(0)?.Description ?? e.PropertyName;

The enumeration is probably not entirely null-safe though, and it needs at least one object in your list (or rather your ObservableCollection) of domain objects. If you're sure about what type of domain object you've got as a source for the grid, you can simply do this instead. Should be faster and safer.

private void SomeGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    var propInfo = typeof(SomeDomainObject).GetProperty(e.PropertyName);
    var toolTip = propInfo?.GetCustomAttributes<DescriptionAttribute>()
        ?.ElementAtOrDefault(0)?.Description ?? e.PropertyName;

And finally, to set the tooltip on the header (still in the SomeGrid_AutoGeneratingColumn event method):

var headerStyle = new Style(typeof(DataGridColumnHeader));
headerStyle.Setters.Add(new Setter(ToolTipService.ToolTipProperty, toolTip));
e.Column.HeaderStyle = headerStyle;
1
bh_earth0 On

tooltiptext for specific cell:

DataGridView1.Rows[3].Cells["colnameX"].ToolTipText = " hover and see me";

adding tooltip to dynamically added rows specific cell

private void DataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
    for (int index = e.RowIndex; index <= e.RowIndex + e.RowCount - 1; index++)                           
    {
        DataGridViewRow row = DataGridView1.Rows[index];
        row.Cells["colnameX"].ToolTipText = " hover and see me";

    }
}