-6

I set Tooltip for a DataGridTemplateColumn like this:

<DataGridTemplateColumn.Header>
<TextBlock Text="Current" ToolTip="Price" ToolTipService.InitialShowDelay="0" ToolTipService.Placement="Top" ToolTipService.ShowDuration="999999" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
</DataGridTemplateColumn.Header>

How can I get the tooltip data in code?

Joan Venge
  • 315,713
  • 212
  • 479
  • 689
  • just [find](https://stackoverflow.com/a/17144293/2430796) your textblock and you can access the tooltip: `yourtextblockobject.ToolTip` (see [TextBlock documentation](https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.textblock?view=net-5.0)) – Tanque Sep 09 '21 at 09:41
  • Thanks I tried something like this but it throws and exception: Utility.GetFirstVisualChild ( e.Column ); – Joan Venge Sep 09 '21 at 14:08
  • @Tanque: Are you sure this can be done for data grid columns? This guy claims they are not part of the visual tree: https://stackoverflow.com/questions/7660967/wpf-error-cannot-find-governing-frameworkelement-for-target-element – Joan Venge Sep 09 '21 at 14:53
  • that answer is about the scope of datacontext in the visual tree and problems with that. According to your code above you don't use Databinding for the header, so please edit your question to better reflect your problem and what your current approach is. – Tanque Sep 10 '21 at 07:48

2 Answers2

2

Put the TextBlock in the HeaderTemplate of the column:

<DataGridTemplateColumn x:Name="col">
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            <TextBlock Text="Current" ToolTip="Price" ToolTipService.InitialShowDelay="0" ToolTipService.Placement="Top"
                       ToolTipService.ShowDuration="999999" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>
</DataGridTemplateColumn>

...and find it in using the VisualTreeHelper:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var columns = FindVisualChildren<System.Windows.Controls.Primitives.DataGridColumnHeader>(dataGrid)?
        .ToArray();

    if (columns != null)
    {
        int columnIndex = 1;
        if (columns.Length > columnIndex)
        {
            var textBlock = FindVisualChildren<TextBlock>(columns[columnIndex])?
            .FirstOrDefault();
            if (textBlock != null)
            {
                string tooltip = textBlock.ToolTip?.ToString();
                //...
            }
        }
    }
}

private static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
        if (child is T t)
            yield return t;

        foreach (T childOfChild in FindVisualChildren<T>(child))
            yield return childOfChild;
    }
}
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Thanks a lot. Is it possible to pass a e.Column which is DataGridColumn directly instead of looping? I am implementing the code based on the currently clicked column in the sorting event: void DataGrid_Sorting ( object sender, DataGridSortingEventArgs e ) I just don't know how I can get the column header from e.Column. e.Column.Header is object type. – Joan Venge Sep 09 '21 at 16:17
  • "e.Column.Header is object type" - did you try GetType() on that object so you know to what you want to cast that object? – Tanque Sep 10 '21 at 07:23
  • Also could you please update your question with that information – Tanque Sep 10 '21 at 07:28
  • "Like the Content property of a ContentControl, the Header can be any type." - taken from the last paragraph in [this](https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.headeredcontentcontrol.header?view=net-5.0#System_Windows_Controls_HeaderedContentControl_Header) documentation. So in above scenario probably something like `e.Column.Header as TextBlock` – Tanque Sep 10 '21 at 07:38
  • 1
    Don't update your question. Ask a new one if you have another issue. – mm8 Sep 10 '21 at 13:53
0

My guess from your comment on @mm8 answer:

private void DataGrid_Sorting( object sender, DataGridSortingEventArgs e ) 
{
    var myHeaderItem = e.Column.Header as TextBlock;
    Console.WriteLine(myHeaderItem?.ToolTip.ToString());
}
Tanque
  • 315
  • 3
  • 16