2009-12-31 3 views
0

J'ai un DataGridTextColumn dans un Silverlight 4 DataGrid et je veux définir une valeur ToolTip sur la colonne qui est différente de la valeur liée.Créer une info-bulle sur Silverlight DataGridTextColumn qui est différent du contenu de la cellule liée

Je sais que je peux le faire avec une colonne basée sur un modèle assez facilement - mais cela ajoute une énorme quantité de XAML supplémentaire et la rend lourde à lire et à maintenir.

Cela fonctionne, mais beaucoup de code supplémentaire - surtout si jamais besoin de changer le modèle

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

Je voudrais trouver une bonne façon de le faire soit avec un style ou héritée classe. Comme je l'ai dit, mon objectif principal est de réduire le ballonnement dans le XAML pour quelque chose d'aussi trivial qu'une infobulle de la meilleure façon possible.

Il existe quelques questions de stackoverflow similaires avec des solutions telles que this et this, mais elles affichent toutes deux la même valeur de l'info-bulle que le contenu de la cellule (par exemple, lorsqu'elle déborde). Bien que ce soit souvent ce que vous voulez, j'essaie de montrer une info-bulle différente du contenu de la cellule.

J'ai trouvé quelques sample code for an inherited class (faites défiler jusqu'à la fin), que j'ai essayé de modifier mais je suis resté bloqué parce que ma connaissance de XAML n'est pas à la hauteur et je ne veux pas passer toute la nuit là-dessus! Cet exemple particulier apparaît comme si cela fonctionnait, mais cela ressemble à un bidouillage et je pense qu'essayer de le modifier pour fonctionner avec deux propriétés de dépendance va être encore plus important.

PS. Je m'attendrais à ce qu'une sous-classe bien écrite me facilite la liaison d'autres propriétés telles que TextTrimming.

Répondre

0

Essayez de mettre ce style dans votre dictionnaire de ressources:

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

Pour activer la liaison à une propriété, comme vous avez demandé dans le commentaire, vous devez faire preuve de créativité. Ce que j'ai fait était de créer deux propriétés jointes ToolTipBinding et IsToolTipBindingEnabled. Le ToolTipBinding est défini sur la colonne pour déterminer l'info-bulle, similaire à la propriété Binding qui détermine le contenu de la cellule, et le IsToolTipBindingEnabled est défini sur true sur l'objet DataGridCell en utilisant un style similaire à celui que j'ai mentionné ci-dessus.

Ensuite, j'ai écrit du code de sorte que lorsque la cellule est chargée, la liaison de sa colonne parente est appliquée à sa propriété ToolTip.

est ici la classe d'extension:

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

Exemple d'utilisation 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> 
+0

merci, mais si je veux lier à quelque chose d'autre que le courrier électronique –

+0

Il vous allez, il a fallu une certaine créativité bien, peut-être pas optimal, mais c'est bon :-) –

+0

Juste un petit commentaire, mais je ne pensais pas que Silverlight supportait le 'x: Type' dans le' TargetType'? –

Questions connexes