前提・実現したいこと
上画像のような形をしたコントロールを作成したいです。
画像は透過pngで、透過部をクリックしてもクリックイベントを発生しないようにしたいです。
自作コントロールにて強引に作成してみましたが、可能ならばボタンスタイルやテンプレートで作成したいと考えております。
該当のソースコード
下記のコードはImageを継承したコントロールにクリックイベントを追加して無理やり作成したものです。
C#
1using System.Drawing; 2using System.Drawing.Imaging; 3using System.Windows; 4using System.Windows.Input; 5using System.Windows.Media.Imaging; 6 7namespace ImageButtonTest 8{ 9 public class ImageButton : System.Windows.Controls.Image 10 { 11 /// <summary> 12 /// 設定された画像の透明領域(アルファ値ゼロ)以外がクリックされたときに発生します。 13 /// </summary> 14 public event MouseButtonEventHandler Click; 15 16 /// <summary> 17 /// マウスボタンを押し上げたときに発生します。 18 /// </summary> 19 /// <param name="e">イベントデータ</param> 20 protected override void OnMouseUp(MouseButtonEventArgs e) 21 { 22 var imageSource = Source as BitmapSource; 23 if (imageSource == null)return; 24 25 var clickEventFlag = false; 26 27 if (Click != null) 28 { 29 // クリック位置を取得する 30 var point = (e.GetPosition(this)); 31 32 // ボタンサイズを考慮し、画像上での座標を求める 33 point = new System.Windows.Point(point.X * ((double)imageSource.PixelWidth / ActualWidth), 34 point.Y * ((double)imageSource.PixelHeight / ActualHeight)); 35 36 // クリックした座標の色を取得する 37 var color = GetColorForPoint(imageSource, point); 38 39 if (color.A != 0) 40 { 41 // クリック箇所のアルファ値がゼロでないときは透過部でないと判断する 42 clickEventFlag = true; 43 } 44 } 45 46 if (clickEventFlag == true) 47 { 48 // マウスクリックイベントを発生させるので、現在のイベントのハンドルはキャンセルしておく 49 e.Handled = true; 50 Click(this, e); 51 } 52 else 53 { 54 // 通常のマウスアップイベントを発生させる 55 base.OnMouseUp(e); 56 } 57 } 58 59 /// <summary> 60 /// ビットマップソースに設定された画像の指定の色を取得します。 61 /// </summary> 62 /// <param name="bitmapSourc">色を取得したいビットマップソース</param> 63 /// <param name="point">座標</param> 64 /// <returns></returns> 65 private System.Windows.Media.Color GetColorForPoint(BitmapSource bitmapSourc, System.Windows.Point point) 66 { 67 // まずはビットマップソースをビットマップ画像に変換する 68 var bitmap = ConvertBitmapSourceToBitmap(bitmapSourc); 69 70 // 指定座標の色を取得する(この時点では「System.Drawing.Color」型) 71 var color = bitmap.GetPixel((int)point.X, (int)point.Y); 72 73 // 取得した色を「System.Windows.Media.Color」型に変換して戻す 74 return System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B); 75 } 76 77 /// <summary> 78 /// ビットマップソースをビットマップ画像に変換します。 79 /// </summary> 80 /// <param name="bitmapSource"></param> 81 /// <returns></returns> 82 private Bitmap ConvertBitmapSourceToBitmap(BitmapSource bitmapSource) 83 { 84 var bitmap = new Bitmap(bitmapSource.PixelWidth, 85 bitmapSource.PixelHeight, 86 System.Drawing.Imaging.PixelFormat.Format32bppPArgb); 87 BitmapData bitmapData = null; 88 89 var rect = new Rectangle(System.Drawing.Point.Empty, bitmap.Size); 90 try 91 { 92 bitmapData = bitmap.LockBits(rect, 93 ImageLockMode.WriteOnly, 94 System.Drawing.Imaging.PixelFormat.Format32bppPArgb); 95 96 bitmapSource.CopyPixels(Int32Rect.Empty, 97 bitmapData.Scan0, 98 bitmapData.Height * bitmapData.Stride, 99 bitmapData.Stride); 100 } 101 catch 102 { 103 bitmap.Dispose(); 104 bitmap = null; 105 throw; 106 } 107 108 bitmap.UnlockBits(bitmapData); 109 110 return bitmap; 111 } 112 } 113} 114
開発環境
Visual Studio 2017
.NET Framework 4.8
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/10 12:10