web-dev-qa-db-fra.com

Afficher l'info-bulle WPF si nécessaire

J'ai un TextBlock à l'intérieur d'un contrôle de taille limitée. Si le texte est trop long pour tenir dans le contrôle, j'aimerais afficher une info-bulle avec le texte intégral. C'est un comportement classique que vous connaissez sûrement dans de nombreuses applications.

J'ai essayé d'utiliser un convertisseur pour convertir la largeur de TextBlock dans Visibility de Tooltip.

<GridViewColumn.CellTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding Text}">
            <TextBlock.ToolTip>
                <ToolTip 
                    DataContext="{TemplateBinding Content}" 
                    Visibility="{Binding Converter={StaticResource visConvert}}">

                        <TextBlock Text="{Binding Text}"></TextBlock>
                </ToolTip>
            </TextBlock.ToolTip>
        </TextBlock>
    </DataTemplate>
</GridViewColumn.CellTemplate>

Le problème est que dans le convertisseur:

public object Convert(object value, ...

'valeur' ​​est l'élément DataBound. Je voudrais que la «valeur» soit le TextBlock, observe sa largeur et la compare à GridViewColumn.Width.

21
Martin Konicek

Je l'ai compris, l'info-bulle a PlacementTarget propriété qui spécifie l'élément d'interface utilisateur qui contient l'info-bulle. Au cas où quelqu'un en aurait besoin:

<TextBlock Text="{Binding Text}">
    <TextBlock.ToolTip>
        <ToolTip 
             DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}" 
             Visibility="{Binding Converter={StaticResource toolVisConverter}}">
             <TextBlock Text="{Binding Text}"/>  <!-- tooltip content -->
         </ToolTip>
    </TextBlock.ToolTip>
</TextBlock>

Et écrivez ensuite un convertisseur qui convertit TextBlock en visibilité (basé sur la largeur de TextBlock).

30
Martin Konicek

Ok, alors pourquoi utiliser uniquement la méthode XAML? Cela marche:

<TextBlock Text="{Binding Text}"
     IsMouseDirectlyOverChanged="TextBlock_IsMouseDirectlyOverChanged" >
     <TextBlock.ToolTip>
     <ToolTip Visibility="Collapsed">
         <TextBlock Text="{Binding Text}"></TextBlock>
     </ToolTip>
     </TextBlock.ToolTip>
</TextBlock>

dans Control.xaml.cs:

private void TextBlock_IsMouseDirectlyOverChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    bool isMouseOver = (bool)e.NewValue;
    if (!isMouseOver)
        return;
    TextBlock textBlock = (TextBlock)sender;
    bool needed = textBlock.ActualWidth > 
        (this.listView.View as GridView).Columns[2].ActualWidth;
    ((ToolTip)textBlock.ToolTip).Visibility = 
        needed ? Visibility.Visible : Visibility.Collapsed;
}
4
Martin Konicek

Je pense que vous devez examiner un déclencheur ControlTemplate pour résoudre ce problème. Malheureusement, les déclencheurs ControlTemplate comparent toujours avec une valeur spécifique, ni inférieure ni supérieure à. Vous pouvez le faire apparaître par exemple. si la largeur = 100, pas la largeur <100.

0
Zyphrax