I'm customizing the DataGridCells to have a small triangle in the corner with a tooltip. This triangle should only show if the tooltip has content and the content of the tooltip will come from the ItemsSource of the DataGrid.
DataGrid with the triangle in the corner:
Right now I created an attached property called Hint which will bind to the property of the ItemsSource that would have the content of the tooltip.
public class HintAttachedProperty
{
public static void SetHint(DependencyObject obj, string text)
{
obj.SetValue(HintProperty, text);
}
public static string GetHint(DependencyObject obj)
{
return obj.GetValue(HintProperty)?.ToString() ?? string.Empty;
}
public static readonly DependencyProperty HintProperty =
DependencyProperty.RegisterAttached("Hint", typeof(string), typeof(HintAttachedProperty), new FrameworkPropertyMetadata(null));
}
The xaml of the DataGrid, now the attached property hint is set with the value "A test":
<local:CustomDataGrid x:Name="datagrid"
AutoGenerateColumns="False"
ItemsSource="{Binding ItemsCollection}"
ClipboardCopyMode="IncludeHeader"
EnableRowsMove="True"
AlternatingRowBackground="LightBlue"
AlternationCount="2">
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="IsChecked" Binding="{Binding IsChecked}"/>
<DataGridTextColumn x:Name="Test"
local:IsHighLightedAttachedProperty.IsHighLighted="True"
local:HintAttachedProperty.Hint="A test"
Header="ExperienceInMonth"
Binding="{Binding ExperienceInMonth}">
</DataGridTextColumn>
<DataGridTemplateColumn Header="References">
...
</DataGridTemplateColumn>
<DataGridTextColumn Header="EmployeeName" Binding="{Binding EmployeeName}"/>
<DataGridTextColumn Header="EmployeeAge" Binding="{Binding EmployeeAge}" />
</DataGrid.Columns>
</local:CustomDataGrid>
And here is the style for the DataGridCell which controls the visibility of the triangle and should bind the attached property to the content of the tooltip:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border x:Name="borderSides" BorderThickness="2,0,2,0" Background="Transparent" BorderBrush="Transparent" SnapsToDevicePixels="True">
<Border x:Name="borderTopBottom" BorderThickness="0,2,0,2" Background="Transparent" BorderBrush="Transparent" SnapsToDevicePixels="True">
<Grid>
<Grid x:Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<Polygon x:Name="pol" ToolTip="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource HintConverter}}" Grid.Column="1" HorizontalAlignment="Right" Points="5,0 10,0, 10,5" Stroke="Black" Fill="Black" >
</Polygon>
</Grid>
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource HintConverter}}" Value="{x:Static sys:String.Empty}">
<Setter TargetName="pol" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource HintConverter}}" Value="{x:Null}">
<Setter TargetName="pol" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In the binding {Binding RelativeSource={RelativeSource Self}, Converter={StaticResource HintConverter}} I'm using a converter of the content of the DataGridCell to get the value of the attached property, because when I was doing {Binding path=(local:HintAttachedProperty.Hint)} It always returned null.
Code of the converter:
public class HintConverters : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
DataGridCell dgc = value as DataGridCell;
if (dgc != null)
{
DataGridColumn col = dgc.Column;
if (col != null)
{
var hint = HintAttachedProperty.GetHint(col);
return hint;
}
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
When debugging I can see in the converter how the value is "A test" and consequently is not hidding the triangle, but when I put the cursor over the tooltip is empty:
Value of hint:
Tooltip is empty:
On the other hand, if I directly bind to a property of the ItemsSource in the style, for example the Employee Name,ToolTip="{Binding EmployeeName}" it works perfectly:
How can I bind the value of and attached property to a property? Is this possible? Maybe I should go in another direction?
Thanks for your attention