Search code examples
xamlwindows-runtimewinrt-xamlwinrt-xaml-toolkit

WinRT - ImageButton for transparent PNGs


I'm using XAML Toolkit ImageButton control to be able to create normal and pressed states for a button. Code is:

<toolkit:ImageButton NormalStateImageSource="ms-appx:///Assets/1_off.png"
                         PressedStateImageSource="ms-appx:///Assets/1_on.png"
                         Width="500"
                         Height="200">
</toolkit:ImageButton>

Issue I'm facing is, say I have a shape which isn't rectangle or square. For example I have PNGs for star and arrow object. Is there a way to set their boundary corresponding to shape? If not, please advice the best approach to handle such scenarios.


Solution

  • There are two options I tried

    1. When clicking using mouse or touch - you'd check the last position of the pointer before click and see if the image in your button has a non-transparent pixel at that position.

      • Pros:
        • It's simpler than option 2.
        • You get most precise information
      • Cons:
        • You can't tell if a button got clicked with mouse, touch, pen, keyboard or by narrator using automation, so you could end up filtering out keyboard clicks just because the mouse cursor is a bit off. You could possibly use some heuristics like how long ago was the pointer move or pointer down event before the click event, but it's a bit hacky and might be unreliable.
    2. Generate a vector path for your image and put it in the button template as a Path element with Fill="Transparent", then mark any other non-transparent or hit testable template elements (buttons, borders with Background="Transparent", etc.) as IsHitTestVisible="false".

      • Pros:
        • Doesn't break any input methods
        • Can be quite precise
        • For some shapes like a circle - the Path.Data could be quite simple or you could even use something like an Ellipse element instead
      • Cons:
        • You need to generate the path somehow
        • A complex path might adversely affect performance

    A better solution overall in most cases is to leave the hit-testable area rectangular. The reason is - an arbitrary shape is a finicky and unreliable hit test target so it makes clicking your button more difficult. Using the default rectangular border or at most - an ellipse shape is a lot simpler and more usable.