Событие нажатия кнопки неправильной PNG в WPF.

Мне нужен кнопка неправильной формы в WPF. Я делаю это таким образом, используя XAML:

<Button Name="toggleButton" Click="toggleButton_Click" Canvas.Left="177" Canvas.Top="0">
  <Button.Template>
    <ControlTemplate>
      <Image Source="ball.png" />
    </ControlTemplate>
  </Button.Template>
</Button>

Мое изображение ball.png - это изображение PNG с шариком с прозрачной областью вокруг него. Кнопка отображается правильно, но обработчик события Click выполняется, даже когда я кликаю по прозрачной части изображения.

Есть ли способ создать неправильные кнопки, используя прозрачные PNG?

Спасибо, Михал

7
задан Michał Fronczyk 28 August 2010 в 20:50
поделиться

1 ответ

Вы можете создать класс, наследуемый от Image и переопределяющий HitTestCore так, чтобы он не реагировал на проверку попадания в прозрачных частях изображения, а затем использовать этот класс в своем шаблоне вместо простого Изображение.

Вот пример, хотя код для проверки прозрачных пикселей не очень надежен, поскольку он делает некоторые предположения об источнике изображения и формате пикселей. Если у вас уже есть код для проверки прозрачных пикселей, вам следует подключить его.

public class TransparentImage
    : Image
{
    protected override HitTestResult HitTestCore(
        PointHitTestParameters hitTestParameters)
    {
        // Get value of current pixel
        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);
        // Check alpha channel
        if (pixels[3] < 10)
        {
            return new PointHitTestResult(this, hitTestParameters.HitPoint);
        }
        else
        {
            return null;
        }
    }

    protected override GeometryHitTestResult HitTestCore(
        GeometryHitTestParameters hitTestParameters)
    {
        // Do something similar here, possibly checking every pixel within
        // the hitTestParameters.HitGeometry.Bounds rectangle
        return base.HitTestCore(hitTestParameters);
    }
}
13
ответ дан 6 December 2019 в 15:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: