0

DataGridTextColumn在 Silverlight 4 中有一个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 中的一些像工具提示这样微不足道的东西。

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

我确实找到了一些继承类的示例代码(滚动到结束),我试图修改它,但因为我的 XAML 知识没有达到标准而卡住了,我不想整夜都在这上面!这个特定的例子看起来很有效,但它看起来像是一个 hack,我认为尝试修改它以使用两个依赖属性将是一个更大的问题。

PS。我希望编写良好的子类可以让我轻松绑定其他属性,例如 TextTrimming。

4

1 回答 1

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>
于 2009-12-31T07:02:24.033 回答