ドラッグ&ドラッグで画像を移動させて連結したいの続きです。今回は画像をそのままではなくトリミングされた画像を連結させます。

まずTreeNodeをダブルクリックしたらダイアログを表示させます。それ以外の部分は前回と同じです。

さてどのようなダイアログを表示するかですがScrollPictureBoxを左右に配置して左側のScrollPictureBoxをドラッグするとそこに描画されているBitmapがトリミングされます。またNumericUpDownコントロールの値を変更することでもトリミングできます。トリミングされたBitmapは右側のScrollPictureBoxに表示されます。

最初に見た目の問題に関する部分です。

コンストラクタ内で自作メソッド InitNumericUpDowns()を実行してNumericUpDownコントロールに自由に値を設定できるようにしています。またイベントハンドラ Form1_Load内で左右に同じ大きさのScrollPictureBoxを表示するための処理をしています。

次にプロパティにかんする部分です。プロパティでアップダウンコントロールの値を変更したり取得できるようにします。アップダウンコントロールだけでなくチェックボックスやScrollPictureBoxに描画されるBitmapも同様です。

ダイアログがLoadされたらTrimmedBitmapプロパティにSourceBitmapをトリミングして得られた画像を表示します。

GetTrimmedBitmap()メソッドはアップダウンコントロールの値からSourceBitmapをトリミングして得られるBitmapを取得するためのもので、GetEnlargedBitmap(Bitmap srcBitmap)メソッドはアップダウンコントロールの値とチェックボックスの状態からトリミングして得られたBitmapを拡大縮小したBitmapを取得するためのものです。

ドラッグされたら画像をトリミングします。トリミングされる部分の境界線も描画されるようにScrollPictureBox.DrawByDrag.DoesShowをtrueに変更します。

ドラッグ&ドロップが終わったらScrollPictureBox.FinishedDragRectangleイベントが発生するのでイベントハンドラScrollPictureBox1_FinishedDragRectangle内で適切な処理をおこないます。ここではトリミングで得られたBitmapを拡大縮小してTrimmedBitmapプロパティにセットするとともに切り捨てられた上下左右の値をアップダウンコントロールにセットしています。

またドラッグ&ドロップではなくアップダウンコントロールで値が変更された場合もトリミング処理がおこなわれます。この処理がおこなわれるのは値が変更されたアップダウンコントロールと this.ActiveControl が同じときだけ(ユーザーによって値が変更された場合だけ)です。アップダウンコントロールでBitmapの幅、高さが変更されたときの処理も同様です。

[適用]ボタンが押されたときは変更を反映させなければならないのですが、その通知をする必要があります。そこでApplyイベントを定義します。これで[適用]ボタンが押されたときにはイベントが発生します。

// [適用]ボタンが押されたときの処理とイベント

×ボタンがおされたらフォームを閉じるのではなく非表示にします。

Form1でTreeNodeがダブルクリックされたら自作メソッド ShowFormForTrimming()が呼び出されます。

FormForTrimmingが生成されたらそれをリストに格納して次に同じTreeNodeがダブルクリックされたら再利用します。同じTreeNodeが何度ダブルクリックされてもダイアログはひとつしか生成されないようにしています。

ShowFormForTrimming()メソッドのなかですでに生成されているダイアログがあるか調べます。最小化されている場合やほかのウィンドウの下に隠れている場合は最前面に表示させます。この処理のためにAPI関数 ShowWindow(IntPtr hWnd, uint Msg)を使っています。

FormForTrimmingオブジェクトを生成したらApplyイベントが処理できるようにイベントハンドラ FormForTrimming_Applyを追加します。そのあと必要なプロパティを設定してf.Show()を実行します。

次にApplyイベントが発生したときの処理ですが、FormForTrimmingオブジェクトから必要なプロパティを取得してShowBitmaps()メソッドを実行します。これで変更が反映されます。

新しくファイルを読み込むときやTreeNodeを削除するときは対応するFormForTrimmingオブジェクトが存在する場合に使われることはないのでMenuItemOpenFile_Click(object sender, EventArgs e)やMenuItemdDeleteNode_Click(object sender, EventArgs e)のなかでDisposeしています(前回の記事参照)。