Search code examples
wpfimagetooltipedge-detection

WPF image tooltip edge detection


I'm a bit new to WPF but I'm having an issue were I'm trying to place a tooltip over an image or button with a background image. Basically what I'm trying to do is I want the tooltip to only show up where the image actually exists and not the transparency. This is an issue because as a button or image uses a rectangle in which it is stored the tooltip will be displayed within that area aswell.

Here is an example button (ignore the poor design but i need a complex shape to give you an idea)

Exmaple:1

Here is the edge of an image/button

Exmaple:1

Printscreen didn't capture the mouse, but imagine that the mouse is not actually hovering over the shape and that it is within the area of the imagebox/button.

Exmaple:1 http://i1109.photobucket.com/albums/h426/Melkirth/Imagearea.png

This is a small example of my actual code

    <Button Height="160" Width="240" BorderThickness="0" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
        <Button.Background>
            <ImageBrush ImageSource="Images/Cloud1.png"></ImageBrush>
        </Button.Background>
        <Button.ToolTip>
            <TextBlock Margin="10" FontSize="14">Click me to begin your test</TextBlock>
        </Button.ToolTip>
    </Button>

Solution

  • Taken from this answer to a similar question:

    Specialized Image Class:

    public class OpaqueClickableImage : Image
        {
            protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
            {
                var source = (BitmapSource)Source;
                var x = (int)(hitTestParameters.HitPoint.X / ActualWidth * source.PixelWidth);
                var y = (int)(hitTestParameters.HitPoint.Y / ActualHeight * source.PixelHeight);
                var pixels = new byte[4];
                source.CopyPixels(new Int32Rect(x, y, 1, 1), pixels, 4, 0);
                if (pixels[3] < 10) return null;
                return new PointHitTestResult(this, hitTestParameters.HitPoint);
            }
        }
    

    XAML:

    <Window x:Class="MiscSamples.ImageButton"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:MiscSamples"
            Title="ImageButton" Height="300" Width="300">
        <Grid Background="Green">
            <Button VerticalAlignment="Center" HorizontalAlignment="Center"
                    ToolTip="Hello!!">
                <Button.Template>
                    <ControlTemplate>
                        <local:OpaqueClickableImage Source="./Resources/SomeImage.png"/>
                    </ControlTemplate>
                </Button.Template>
            </Button>
        </Grid>
    </Window>
    

    That will make the tooltip only shown when the mouse is over non-transparent areas of the image.