I have a DataGridTextColumn
in a Silverlight 4 DataGrid
and I want to set a ToolTip value on the column that is different from the bound value.
I know I can do this with a templated column quite easily - but it adds a huge amount of extra XAML and makes it cumbersome to read and maintain.
This works, but is a lot of extra code - especially if ever need to change the template
<data:DataGridTemplateColumn Header="Name" Width="*"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock TextTrimming="WordEllipsis" Text="{Binding FullName}" ToolTipService.ToolTip="{Binding Email}" Width="Auto" Margin="5" /> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> </data:DataGridTemplateColumn>
I'd like to find a nice way to do this with either a Style or inherited class. Like I said my main goal is to reduce bloat in the XAML for something so trivial as a tooltip in the best possible way.
There are a few similar stackoverflow questions with solutions like this and this, but they both show the same tooltip value as the contents of the cell (for instance when it overflows). While this is often what you want - I'm trying to show a different tooltip to the cell's contents.
I did find some sample code for an inherited class (scroll to end), which i tried to modify but got stuck becasue my XAML knowledge isn't up to par and I don't want to spend all night on this! This particular example appears like it works, but it looks like quite a hack and I think trying to modify it to work with two dependency properties is going to be an even bigger one.
PS. I would expect that a well written subclass would make it easy for me to bind other properties such as TextTrimming also.
Answer: 1
Try to put this style in your resource dictionary:
<Style TargetType="{x:Type data:DataGridCell}"> <Setter Property="ToolTip" Value="{Binding EMail}"/> </Style>
To enable binding to any property, as you requested in the comment, you need to get creative. What I did was create two attached properties ToolTipBinding
and IsToolTipBindingEnabled
. The ToolTipBinding
is set on the column to determine the tooltip, similar to the Binding
property that determines the content of the cell, and the IsToolTipBindingEnabled
is set to true
on the DataGridCell
object using a style similar to the one I mentioned above.
Then, I wrote code so that when the cell is loaded, the binding from its parent column is applied to its ToolTip
property.
Here's the extension class:
public class DGExtensions { public static object GetToolTipBinding(DependencyObject obj) { return obj.GetValue(ToolTipBindingProperty); } public static void SetToolTipBinding(DependencyObject obj, object value) { obj.SetValue(ToolTipBindingProperty, value); } public static readonly DependencyProperty ToolTipBindingProperty = DependencyProperty.RegisterAttached( "ToolTipBinding", typeof(object), typeof(DGExtensions), new FrameworkPropertyMetadata(null)); public static bool GetIsToolTipBindingEnabled(DependencyObject obj) { return (bool)obj.GetValue(IsToolTipBindingEnabled); } public static void SetIsToolTipBindingEnabled( DependencyObject obj, bool value) { obj.SetValue(IsToolTipBindingEnabled, value); } public static readonly DependencyProperty IsToolTipBindingEnabled = DependencyProperty.RegisterAttached( "IsToolTipBindingEnabled", typeof(bool), typeof(DGExtensions), new UIPropertyMetadata(false, OnIsToolTipBindingEnabledChanged)); public static void OnIsToolTipBindingEnabledChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGridCell cell = d as DataGridCell; if (cell == null) return; bool nv = (bool)e.NewValue, ov = (bool)e.OldValue; // Act only on an actual change of property value. if (nv == ov) return; if (nv) cell.Loaded += new RoutedEventHandler(cell_Loaded); else cell.Loaded -= cell_Loaded; } static void cell_Loaded(object sender, RoutedEventArgs e) { DataGridCell cell = sender as DataGridCell; if (cell == null) return; var binding = BindingOperations.GetBinding( cell.Column, ToolTipBindingProperty); if (binding == null) return; cell.SetBinding(DataGridCell.ToolTipProperty, binding); // This only gets called once, so remove the strong reference. cell.Loaded -= cell_Loaded; } }
Example XAML usage:
<Window.Resources> <Style TargetType="{x:Type tk:DataGridCell}"> <Setter Property="dge:DGExtensions.IsToolTipBindingEnabled" Value="True"/> </Style> </Window.Resources> <Grid> <tk:DataGrid ItemsSource="{Binding TheList}" AutoGenerateColumns="False"> <tk:DataGrid.Columns> <tk:DataGridTextColumn Header="PropA" Binding="{Binding PropA}" dge:DGExtensions.ToolTipBinding="{Binding PropB}"/> <tk:DataGridTextColumn Header="PropB" Binding="{Binding PropB}"/> </tk:DataGrid.Columns> </tk:DataGrid> </Grid>
by : Aviad P.http://stackoverflow.com/users/235648
No comments:
Post a Comment
Send us your comment related to the topic mentioned on the blog