Search code examples
wpf

ToolTip from a background object


I like to show some locations on a background image. For that I put a ListBox (with a Canvas as ItemsPanel) on top of an Image inside a Grid, something like that:

<Grid>
    <Image Source="{Binding ImageSource}"
           ToolTipService.ToolTip="{Binding ImageToolTip}" />

    <ListBox ItemsSource="{Binding ListSource}"
             Background="Transparent">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas IsItemsHost="True" />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Canvas.Left" Value="{Binding Left}" />
                <Setter Property="Canvas.Top" Value="{Binding Top}" />
                <Setter Property="Padding" Value="0" />
                <Setter Property="Margin" Value="0" />
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemTemplate>
            <DataTemplate DataType="...">
                <Ellipse Width="10" Height="10"
                         Fill="White"
                         ToolTipService.ToolTip="{Binding Name}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

That works like a charm.

Now I'd like to show information about the background image in the ToolTip of the image. But the ToolTip of the Image does never show up as long as there's the ListBox infront of it.

I already tried to set the Background of the ListBox to Transparent or to {x:Null}, I tried to set the Background of the Canvas to Transparent or to {x:Null}, but nothing helped so far.

In the future I might want to put another ListBox infront of the existing one to show other additional overlays, but I'm afraid as soon as the second ListBox is in place I can't see the ToolTips of the items of the first ListBox anymore, and I might not be able to click on the items of the first ListBox.

Any suggestions?


Solution

  • Even with Background="{x:Null}" the ListBox swallows all mouse events. You may verify that by attaching a MouseMove event handler. This is certainly due to a Border or ScrollViewer element in the ListBox's Template.

    So you would have to modify the Template, e.g. like

    <ListBox ItemsSource="{Binding ListSource}" Background="{x:Null}">
        <ListBox.Template>
            <ControlTemplate TargetType="ListBox">
                <ItemsPresenter/>
            </ControlTemplate>
        </ListBox.Template>
        ...
    </ListBox>
    

    Or you just use an ItemsControl instead of a ListBox:

    <Grid>
        <Image Source="{Binding ImageSource}"
               ToolTipService.ToolTip="{Binding ImageToolTip}" />
    
        <ItemsControl ItemsSource="{Binding ListSource}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="Canvas.Left" Value="{Binding Left}" />
                    <Setter Property="Canvas.Top" Value="{Binding Top}" />
                </Style>
            </ItemsControl.ItemContainerStyle>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Ellipse Width="10" Height="10" Fill="White"
                             ToolTipService.ToolTip="{Binding Name}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>