How to make the style use data from its control?

<DataGrid AutoGenerateColumns="False" ColumnWidth="100"> <DataGrid.Resources> <Style TargetType="DataGridColumnHeader"> <Setter Property="ToolTip" Value="{Binding //тут нужно привязаться к ToolTipText}"/> </Style> </DataGrid.Resources> <DataGrid.Columns> <local:DataGridTextColumnWithHeader Header="!hello" ToolTipText="hello!" /> </DataGrid.Columns> </DataGrid> 

Implementation of DataGridTextColumnWithHeader :

  public class DataGridTextColumnWithHeader : DataGridTextColumn { public string ToolTipText { get { return (string)GetValue(ToolTipTextProperty); } set { SetValue(ToolTipTextProperty, value); } } public static readonly DependencyProperty ToolTipTextProperty = DependencyProperty.Register("ToolTipText", typeof(string), typeof(DataGridTextColumnWithHeader)); } 

    1 answer 1

    Ok, this is actually not so simple, since Column - DataGrid objects are not part of the visual tree, and it's not so easy to reach them.

    But in your case, you can give the column a name, and reach out by name:

     <DataGrid AutoGenerateColumns="False" ColumnWidth="100"> <DataGrid.Resources> <Style TargetType="DataGridColumnHeader"> <Setter Property="ToolTip" Value="{Binding ToolTipText, ElementName=ColumnWithHeader}"/> </Style> </DataGrid.Resources> <DataGrid.Columns> <local:DataGridTextColumnWithHeader x:Name="ColumnWithHeader" Header="!hello" ToolTipText="hello!" /> </DataGrid.Columns> </DataGrid> 

    If you do not want to do the style for each column, you can do without it, using the code behind:

     <DataGrid AutoGenerateColumns="False" ColumnWidth="100" Loaded="OnDGLoaded" Name="DG"> <DataGrid.Columns> <local:DataGridTextColumnWithHeader Header="!hello" ToolTipText="hello!"/> </DataGrid.Columns> </DataGrid> 
     void OnDGLoaded(object sender, RoutedEventArgs e) { foreach (var header in GetVisualChildrenOfType<DataGridColumnHeader>(DG)) { DataGridTextColumnWithHeader column = header.Column as DataGridTextColumnWithHeader; if (column != null) header.ToolTip = column.ToolTipText; } } IEnumerable<T> GetVisualChildrenOfType<T>(FrameworkElement fe) where T : FrameworkElement { T t = fe as T; if (t != null) yield return t; int count = VisualTreeHelper.GetChildrenCount(fe); for (int i = 0; i < count; i++) { FrameworkElement child = VisualTreeHelper.GetChild(fe, i) as FrameworkElement; if (child != null) { foreach (var r in GetVisualChildrenOfType<T>(child)) yield return r; } } } 

    This will assign the tooltip only once, at boot time. If this is not enough, you can set the binding manually, since you have both objects in the OnDGLoaded loop.

    • Sorry, a little wrong asked the question, but already edited. - Lightness
    • @Lightness: Done, check. - VladD
    • And without a name you can not? It is planned to create a set of Column objects, and make one style for them. Or do you have to create your own style for each Column and address the name directly? - Lightness
    • @Lightness: I haven’t found another solution yet. The problem is that DataGridColumnHeader no access to Column . T. k. Column generally can be not in the visual tree. But perhaps, in theory, a solution with code behind. - VladD 7:47 pm
    • I understood. Thank! - Lightness