Click here to Skip to main content
14,240,573 members
Rate this:
Please Sign up or sign in to vote.
See more:
I'm developing a WPF desktop application and I'm trying to have a DataGrid where certain columns have a ToolTip that is from a property on a ViewModel object stored in each "cell" of the DataTable that is the ItemsSource for the DataGrid. I'm AutoGenerating the columns because there are not a fixed number of columns in the data.

I previously asked about the precedence of RowStyle and DataGridColumn.CellStyle (Does DataGrid.RowStyle override DataGridColumn.CellStyle?[^]) and determined that it appears the CellStyle takes precedence.

I can't seem to figure out how, from the XAML of the Style used as the CellStyle, to bind to a property on the actual source object (ViewModel) for the cell.
A DataGridCell doesn't appear to have a path to access to the source object.

Is there a better way to accomplish what I'm attempting?
Posted
Updated 6-Feb-14 8:31am
v2
Comments
CBadger 6-Feb-14 2:24am
   
Did you have a look at this?
http://www.codeproject.com/Articles/10583/DataGrid-Cell-Tooltip
Matt T Heffron 6-Feb-14 14:30pm
   
Alas, this appears to be for a web application, and I'm doing a WPF desktop application, so it is a totally different type of DataGrid.
CBadger 7-Feb-14 0:55am
   
O WPF? Damn sorry man I do not have much xp with forms/apps. More of an ASP.Net coder :-)
Rate this:
Please Sign up or sign in to vote.

Solution 1

I have had a similar problem as far as I understand your question so I hope this will be of tremendous help for you

Flex Tooltip[+]

The example used here is to display a datagrid as a tooltip so might be overkill for what you want to do but I am sure you will be able to figure something out looking through this code as I did with my project ;-)
   
Comments
Matt T Heffron 6-Feb-14 14:27pm
   
Alas, this appears to be for a web application, and I'm doing a WPF desktop application, so it is a totally different type of DataGrid.
Rate this:
Please Sign up or sign in to vote.

Solution 3

I ended up doing this using a value converter for getting the tool tip:
using System;
using System.Data;
using System.Globalization;
using System.Windows.Controls;
using System.Windows.Data;

namespace PreQuant
{
  public class CellToolTipConverter : IMultiValueConverter
  {
    #region IMultiValueConverter Members
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
      if (values == null)
        throw new ArgumentNullException("values");
      if (values.Length != 2)
        throw new InvalidOperationException("Incorrect number of values passed to CellToolTipConverter");
      DataRowView rowView = values[0] as DataRowView;
      if (rowView == null)
        throw new InvalidOperationException("Incorrect type of first (DataRowView) value passed to CellToolTipConverter");
      DataRow row = rowView.Row;
      if (row == null)
        throw new InvalidOperationException("DataRow must not be null");
      DataGridCell cell = values[1] as DataGridCell;
      if (cell == null)
        throw new InvalidOperationException("Incorrect type of second (DataGridCell) value passed to CellToolTipConverter");
      DataGridColumn column = cell.Column;
      if (column == null)
        throw new InvalidOperationException("DataGridColumn must not be null");
      string toolTip = null;
      CellViewModel vm = row[column.SortMemberPath] as CellViewModel;
      // because I also had renamed the columns from the DataTable column names, I used .SortMemberPath
      // It had to repeat the logic of the RowStyle ToolTip generation since the CellStyle supercedes the RowStyle
      // ...
      // Then it could use the CellViewModel to get the cell's toolTip (if the row hasn't already set one...
      toolTip = vm.Information;
      return toolTip;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
      throw new NotImplementedException();
    }
    #endregion
  }
}

And then got the DataRowView and DataGridCell values in the XAML as:
<Style x:Key="CellStyle"
       TargetType="{x:Type DataGridCell}">
  <Setter Property="ToolTip">
    <Setter.Value>
      <MultiBinding Converter="{StaticResource CellToolTip}">
        <Binding />
        <Binding RelativeSource="{RelativeSource Self}" />
      </MultiBinding>
    </Setter.Value>
  </Setter>
</Style>

I assigned the CellStyle to the appropriate columns in the .xaml.cs code-behind.
   
v2
Rate this:
Please Sign up or sign in to vote.

Solution 2

try something like this:
ToolTip="{Binding Path=Content.yourPropertyPath, RelativeSource={RelativeSource TemplatedParent}}"
   
v2
Comments
Matt T Heffron 7-Feb-14 13:41pm
   
No luck. The {RelativeSource TemplatedParent} is null.
Irina Pykhova 7-Feb-14 13:47pm
   
why, if you use it inside the ControlTemplate, it can't be null, it is always the control for which this ControlTemplate is used. Anyway, it would be easier if you can show the simple code and xaml reproducing your problem.
Matt T Heffron 7-Feb-14 14:05pm
   
See my Solution 3, I tried the TemplatedParent in the Setter.Value, not in a ControlTemplate.
Irina Pykhova 7-Feb-14 14:12pm
   
I see. Maybe using ControlTemplate whould be simpler, or you might have to write converters for every different column.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100