Tooltips for indivual cells of a DataGrid

Just recently,  I have been faced with the question on how to add cell dependent tooltips to individual cells of a DataGrid in Silverlight. If you generate the columns by yourself, the task is straight forward by using the appropriate data template for the cell. Something like this:

<Data:DataGrid>
   <Data:DataGrid.Columns>
      <Data:DataGridTemplateColumn>
         <Data:DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
               <TextBlock  Text="{Binding ColumnProperty}"
                    ToolTipService.ToolTip="{Binding ColumnProperty}"/>
            </DataTemplate>
         </Data:DataGridTemplateColumn.CellTemplate>
      </Data:DataGridTemplateColumn>
   </Data:DataGrid.Columns>
</Data:DataGrid>

However, if you let the columns be autogenerated by the grid, things are not so straight forward anymore. One solution which should work in many cases could be to customize or replace a column once it is generated by handling the DataGrid.AutoGeneratedColumn event. This solution is described in detail on MSDN.

A better fitting solution for my problem was to handle the DataGrid.LoadingRow event like this:

private void resultSetGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
   DataGrid dataGrid = sender as DataGrid;
   foreach (DataGridColumn column in dataGrid.Columns)
   {
      string cellValue = GetCellValue(e.Row, column.Header as string);

      if (cellValue != null)
      {
         FrameworkElement element = column.GetCellContent(e.Row);
         ToolTipService.SetToolTip(element, new ToolTipCtrl(cellValue));
      }
   }
}

In GetCellValue you can e.g. use reflection to get the value of the property named like the column header, which should always work with autogenerated columns if you did not change the header of the column by yourself.

private static string GetCellValue(DataGridRow row, string propertyName)
{
   string value = null;
   object boundObject = row.DataContext;

   if (boundObject != null)
   {
        Type type = boundObject.GetType();
        value = type.InvokeMember(propertyName, BindingFlags.GetProperty,
                           null, boundObject, new object[] { }) as string;
   }

   return value;
}
and easy by using a cell template similar to this one:

Ein Gedanke zu „Tooltips for indivual cells of a DataGrid“

Kommentare sind geschlossen.