在Silverlight DataGridTextColumn上创建与绑定单元格内容不同的ToolTip

时间:2009-12-31 03:59:34

标签: wpf silverlight xaml datagridtemplatecolumn

我在Silverlight 4 DataGridTextColumn中有一个DataGrid,我想在列上设置一个与绑定值不同的ToolTip值。

我知道我可以很容易地使用模板化列来实现这一点 - 但是它增加了大量额外的XAML并且使得读取和维护变得很麻烦。

这样可行,但需要更多代码 - 特别是如果需要更改模板

    <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>

我想找一个很好的方法来做一个Style或继承的类。就像我说的那样,我的主要目标是减少XAML中的膨胀,以最好的方式处理工具提示这样的微不足道的事情。

有一些与thisthis等解决方案类似的stackoverflow问题,但它们都显示与单元格内容相同的工具提示值(例如,当它溢出时)。虽然这通常是你想要的 - 我试图向单元格内容显示不同的工具提示。

我确实找到了一些sample code for an inherited class(滚动到结尾),我试图修改但是因为我的XAML知识达不到标准而被卡住了我不想整晚都花在这上面!这个特殊的例子看起来很有效,但它看起来很糟糕,我认为尝试修改它以使用两个依赖属性将是一个更大的。

PS。我希望一个写得很好的子类可以让我很容易绑定其他属性,比如TextTrimming。

1 个答案:

答案 0 :(得分:0)

尝试将此样式放在资源字典中:

<Style TargetType="{x:Type data:DataGridCell}">
    <Setter Property="ToolTip" Value="{Binding EMail}"/>
</Style>

要根据您在评论中的要求启用对任何媒体资源的绑定,您需要获得广告素材。我所做的是创建两个附加属性ToolTipBindingIsToolTipBindingEnabled。列上设置ToolTipBinding以确定工具提示,类似于确定单元格内容的Binding属性,并且IsToolTipBindingEnabled设置为true DataGridCell对象使用类似于我上面提到的样式。

然后,我编写了代码,以便在加载单元格时,其父列的绑定将应用于其ToolTip属性。

这是扩展类:

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;
    }
}

示例XAML用法:

<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>