Search code examples
c#wpftooltiptextblocklistviewitem

How to give the ListViewItem ToolTip precedence over the TextBlock ToolTip?


Given an object such as:

public class Item
{
    public string Foo { get; set; }
    public string Bar { get; set; }
    public int Hidden { get; set; }
}

Simply displayed as:

<Grid>
    <Grid.Resources>
        <!-- style stuff -->
    </Grid.Resources>
    <ListView 
        x:Name="ItemsListView"
        ItemsSource="{Binding AllItems}"
        SelectedValue="{Binding SelectedItem}">
        <ListView.View>
            <GridView>
                <GridViewColumn 
                    Width="75"
                    DisplayMemberBinding="{Binding Foo, Mode=OneWay}"
                    Header="Foo"/>
                <GridViewColumn 
                    Width="75"
                    DisplayMemberBinding="{Binding Bar, Mode=OneWay}"
                    Header="Bar"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

In the Grid.Resources I created the following style to allow a ToolTip to display each cell value on hover:

<Style TargetType="{x:Type TextBlock}">
    <Setter 
        Property="ToolTip"
        Value="{Binding RelativeSource={RelativeSource Self},  Path=Text}"/>
    <Setter
        Property="TextTrimming"
        Value="CharacterEllipsis"/>
</Style>

That works as desired. But now I want to validate a row based on the Hidden property. If the value is -1, outline the row in red and display a TooTip message:

<Style TargetType="{x:Type ListViewItem}">
    <Style.Triggers>
        <DataTrigger
            Binding="{Binding Hidden}"
            Value="-1">
            <Setter Property="BorderBrush" Value="Red"/>
            <Setter Property="ToolTip" Value="Bad Item... Bad!"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

That also works, as long as I'm hovering over the cell borders of the invalid item. The moment I hover over the Foo or Bar cell of the invalid item, the previous ToolTip displaying the cell value is shown.

gif of current working code

How can I get the ListViewItem.ToolTip to override the TextBlock.ToolTip when the row is invalid?


Solution

  • You can set the TextBlock style as follows so that ToolTip will be set in DataTrigger for specified condition. In this case, if ToolTip is not set on GridViewColumn then ListViewItem tooltip will appear automatically.

    <Style TargetType="{x:Type TextBlock}">
        <Setter
            Property="TextTrimming"
            Value="CharacterEllipsis"/>
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Style.Triggers>
            <DataTrigger
                Binding="{Binding Hidden}"
                Value="0">
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},  Path=Text}"/>
            </DataTrigger>
        </Style.Triggers>
     </Style>