目的
実現したい課題は表題そのものです
ここでの着目点は「横スクロール」です
バックグラウンド
C#でPictureBoxに表示した画像にスクロールバーを付け足したい、と云う要望に関しては、dobonさんのサイト(いつもお世話になっております…)でそのものズバリのスマートな回答が スクロールバーを付けて画像を表示する として纏まっています
スクロールバーが出るので、マウスホイールも使えはするのですが、残念ながら縦スクロールしかできません
何とかせねばっ!
スクロールバー連携のおさらい
ちょっと重要なので、軽く対応方法を振り返っておきます
1.Panelを置く
AutoScrollプロパティをtrueにする
2.その上にPictureBoxを置く
Locationプロパティは(0, 0)にする
SizeModeプロパティはAutoSizeにする
DockプロパティはNoneで(ここ重要)
3.PictureBoxのImageプロパティに表示したい画像を放り込む
Panelのサイズに収まらなければ、勝手にスクロールバーが出る(Panel側に)
…では、ホイールでの縦横スクロールについて説明していきましょう
対応方法
まずはホイール回した際のイベントを拾わなければ話は始まりません
これは以下…
public Form1() {
InitializeComponent();
pictureBox1.MouseWheel += PictureBox1_MouseWheel; // <== これを追加
}
なんでか知らんがMouseWheelイベントは[Browsable(false)]で、プロパティウィンドウのイベントリスト内に出てこない為、しょうがないから手で追加します
で、ハンドラの中身は以下です
private void PictureBox1_MouseWheel(object sender, MouseEventArgs e) {
if (Control.ModifierKeys.HasFlag(Keys.Shift))
panel1.AutoScrollPosition = new Point(panel1.HorizontalScroll.Value - e.Delta, panel1.VerticalScroll.Value);
else
panel1.AutoScrollPosition = new Point(panel1.HorizontalScroll.Value, panel1.VerticalScroll.Value - e.Delta);
((HandledMouseEventArgs)e).Handled = true;
}
解説すると———
-
MouseWheelハンドラに流れてきたときに、Shiftキーが押されていればPoint.Xの方・押されていなければPoint.Yの方、をDeltaで調整してあげる - スクロール処理しちゃったので
Handledをtrueにして、もうこれ以上余計な事はしないでくれ! と申し伝える
ここでの重要ポイントは、MouseWheelイベントを捕まえるのはPictureBoxの方で、そのイベントハンドラの中ではPanelのプロパティを触っている、と云う処でしょうか…
PanelのMouseWheelイベントを捕まえた段階では、もう既にスクロール処理が終わってしまっている様で上手くいきません
ここで、おさらいしたPanelとPictureBoxの関係が生きてきます
PictureBoxはPanelの上に乗っているので先にPictureBoxで捕まえて独自のスクロール処理を施した上でHandledにtrueをセットする事により、その裏にあるPanelは「もう自分の出番はないな」とMouseWheelのイベント処理はスキップしてくれる、というカラクリです
〆
これで自作のアプリでも、Excel(Micoroft365の方)やGIMPなどの様にホイール使っての縦横スクロールが実現でき………
と、ここにきて、ふと心配になりました
私のパソコンってホイールの回転、逆向き仕様です
Deltaの調整って設定によらないよね?
「いやー、んなこたねーだろ」と思いながらも———
あ、大丈夫みたいです
さすがにそんな事は無かったという事で…