質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.49%

  • C#

    7391questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • スクロール

    28questions

    スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

【C#】スクロール表示させた画像をマウスホイールやドラッグで操作可能にする方法

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,920

monchiken

score 8

■■■■■実装したいこと■■■■■
画像のパス等が登録されたリンクやボタンを押下するイベントが発生した際、
以下機能が実装されたフォームが表示される仕組みを構築しようとしております。

(1)画像ファイル表示
(2)初期表示は、ウィンドウサイズに収まる大きさに縮小して画像表示
(3)ダブルクリックにより表示方法(原寸大、ウィンドウサイズに収まるよう縮小)が切り替え可能
(4)原寸大表示の際、スクロールバーが表示される
(5)マウスホイールやドラック操作により表示箇所変更可能

■■■■■実装できていないこと■■■■■
上記の内(4)(5)の機能が実装出来ません。現状は以下のとおりです。

(4)
原寸大表示をさせた際、
右側に表示されるスクロールバーは左半分だけ表示され、
下側に表示されるスクロールバーは隠れているため、
ウィンドウサイズ変更しなければどちらもちゃんと見えない状態になります。
複数のサイトを見たところ、スクロール表示に伴い
フォームのSize等を小さくする等はしていないようなのですが、
この場合何が問題でスクロールバーの位置がフォームの表示範囲外になっているのでしょうか。

(5)
ブレイクポイント入れてみても止まらないことから、そもそもイベントが拾えていないようです。
何度もガチャガチャ操作していると、なぜか時々イベントが拾え、
一時的にマウスホイールで上下に画像を動かせるようになり、また動かなくなります。

言い換えると、Panelにイベント追加したものが全て動いていません。
もともと機能(3)を実装する時Panelにイベントを追加し、
clickExpandPictureの最初を以下のようにしていたのですが、
動いてくれなかったためPictureBoxにイベント追加するよう書き換えました。

Panel panel = sender as Panel;
PictureBox box = (PictureBox)panel.Controls.Find("PictureBox", false)[0];

どのように実装すべきなのでしょうか。
皆様のご回答お待ちしております。

■■■■■実際のコード■■■■■

//(1)(2)
private void expandPicture(object sender, EventArgs e)
{
    String fullpath = //画像のフルパス取得

    int scrollBarWidth = new VScrollBar().Width;

    PictureBox box = new PictureBox();
    box.Name = "PictureBox";
    box.SizeMode = PictureBoxSizeMode.Zoom;
    box.Size = new Size(ClientSize.Width - scrollBarWidth, ClientSize.Height - scrollBarWidth);
    box.ImageLocation = fullpath;
    box.DoubleClick += new EventHandler(clickExpandPicture);

    Panel panel = new Panel();
    panel.AutoScroll = true;
    panel.Size = screenSize;
    panel.MouseDown += new MouseEventHandler(dragStartExpandPicture);
    panel.MouseUp += new MouseEventHandler(dragEndExpandPicture);
    panel.MouseMove += new MouseEventHandler(dragExpandPicture);
    panel.MouseWheel += new MouseEventHandler(wheelExpandPicture);
    panel.Controls.Add(box);

    Form pictureForm = new Form();
    pictureForm.Controls.Add(panel);
    pictureForm.Size = ClientSize;
    pictureForm.ShowDialog();
}
//(3)ダブルクリックにより表示方法切り替え
private void clickExpandPicture(object sender, EventArgs e)
{
    PictureBox box = sender as PictureBox;

    if (box.SizeMode == PictureBoxSizeMode.Zoom)
        box.SizeMode = PictureBoxSizeMode.AutoSize;
    else
        box.SizeMode = PictureBoxSizeMode.Zoom;
}
//(5)マウスホイールによるイベント
private void wheelExpandPicture(object sender, MouseEventArgs e)
{
    ScrollableControl control = sender as ScrollableControl;
    var scroll = control.VerticalScroll;

    var maximum = 1 + scroll.Maximum - scroll.LargeChange;
    var delta = -(e.Delta / 120) * scroll.SmallChange;
    var offset = Math.Min(Math.Max(scroll.Value + delta, scroll.Minimum), maximum);

    scroll.Value = offset;
    scroll.Value = offset;
}
//(5)ドラック操作によるイベント
private bool dragFlag = false;
private Point dragStartPoint;
private void dragStartExpandPicture(object sender, MouseEventArgs e)
{
    dragFlag = true;
    dragStartPoint = e.Location;
}
private void dragEndExpandPicture(object sender, MouseEventArgs e)
{
    dragFlag = false;
}
private void dragExpandPicture(object sender, MouseEventArgs e)
{
    if (dragFlag)
    {
        Panel panel = sender as Panel;

        Point currentPosition = new Point(
            dragStartPoint.X - e.Location.X - panel.AutoScrollPosition.X,
            dragStartPoint.Y - e.Location.Y - panel.AutoScrollPosition.Y);
        panel.AutoScrollPosition = currentPosition;
    }

}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

1つ1つ解決していきましょう。
マウスホイールのイベントですが、確か、アクティブなコントロール(親)が受け取る仕様だったはずです。

今回は、Form-Panel-PictureBoxの3層構造ですね。
恐らく、FormがMouseWheelを受け取るようにすると100%受け取れると思います。
Debug.WriteLineで表示させて確認してみてください。

(4)は言いたい事はなんとなくわかるのですが、画像があるといいかなと。
今はこう表示されるけれど、本当はこのスクロールバーをを消したいとかそういう説明は可能でしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    7391questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • スクロール

    28questions

    スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

  • トップ
  • C#に関する質問
  • 【C#】スクロール表示させた画像をマウスホイールやドラッグで操作可能にする方法