DOBON.NET DOBON.NETプログラミング掲示板過去ログ

AutoScrollの動作について

環境/言語:[OS : Windows XP Professional / 言語 : Visual Basic .NET / .NET Framework : 3.0]
分類:[.NET]

【解決したい問題】

いつも参考にさせていただいております。

AutoScrollの動作についてなのですが、例えば、

フォームにPictureBoxを貼り付けて、フォームのAutoScrollをTrueとします。
PictureBoxの高さはフォームの高さとなるように、Resizeで調整します。

以下にそのソースを記述します。
Public Class Form1

 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  PictureBox1.Top = 0
  PictureBox1.Left = 0
  PictureBox1.Height = Me.ClientSize.Height - 1
  Me.AutoScroll = True
 End Sub

 Private Sub Form1_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
  PictureBox1.Height = Me.ClientSize.Height - 1
 End Sub
End Class

そこでお聞きしたいのですが、フォームの高さをマウスでつまんで縮小させると、スクロールバーがフラッシュします。
このスクロールバーを表示しないようにできないでしょうか?

PictureBox内の画像の高さがフォームの高さより小さい場合は、PictureBoxの高さ=フォームの高さ、
大きい場合はフォームにスクロールバーを表示させることをさせたいのです。

ここでは、フォームを利用しておりますが、UserControlで実現させようとしておりますので、そこのところを含み、解決策がありましたら、ご教授ください。
よろしくお願いいたします。
■No24726に返信(tyさんの記事)
> そこでお聞きしたいのですが、フォームの高さをマウスでつまんで縮小させると、スクロールバーがフラッシュします。

SuspendLayout メソッドとApplication.Idle イベントを
利用してリサイズ中の描画を一時停止させるとか・・・

Windows フォームにおけるパフォーマンス向上の実現
http://download.microsoft.com/download/6/9/c/69c09c8a-810b-46c8-b61e-79c4339ea47e/T5-407.ppt
サンプルを書いてみました。
ソースコードは2つのカスタムコントロールと、1つのFormで構成されます。

・PictureBoxEx・・・SizeMode=Zoomのときに、自身の高さとImageの高さが一致するように画像を表示するPictureBox。

・PictureBoxAutoScroll・・・PictureBoxExのコンテナ。Imageの高さと自身の高さを比較し、ScrollBarの
    表示・非表示やImageの描画方法を制御します。UserControlの代わりにScrollableControlで作りました。

・PictureBoxAutoScrollTestForm・・・PictureBoxAutoScrollを表示するだけのテスト用Form。

参考になれば幸いです。
# 私のPC(XPHomeSP3、CeleronM1.5GHz)では、スクロールバーはフラッシュしません

Imports System.IO

Public Class PictureBoxAutoScrollTestForm
    Inherits Form

    Dim PictureBoxAutoScroll1 As New PictureBoxAutoScroll

    Public Sub New()
        Me.PictureBoxAutoScroll1.Dock = DockStyle.Fill
        Me.Controls.Add(Me.PictureBoxAutoScroll1)
    End Sub

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        Me.PictureBoxAutoScroll1.LoadPicture()
        MyBase.OnLoad(e)
    End Sub

End Class


' UserControlの代わりにScrollableControlを使いました
Public Class PictureBoxAutoScroll
    Inherits ScrollableControl

    Dim PictureBox1 As New PictureBoxEx

    Dim _size As Size

    Public Sub New()
        Me.PictureBox1.Location = New Point(0, 0)
        Me.Controls.Add(Me.PictureBox1)
    End Sub

    ' 画像を読み込んでPictureBoxExに表示
    Public Sub LoadPicture()
        Using ofd As New OpenFileDialog
            ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
            If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then
                Using fs As New FileStream(ofd.FileName, FileMode.Open)
                    Me.PictureBox1.Image = Image.FromStream(fs)
                    Me._size = Me.PictureBox1.Image.Size
                End Using
            End If
        End Using

        Me._resizePictureBox()
    End Sub

    Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)
        Me._resizePictureBox()
        MyBase.OnSizeChanged(e)
    End Sub

    ' 画像の高さによって表示方法を変える
    Private Sub _resizePictureBox()
        If Me.ClientSize.Height >= Me._size.Height Then
            Me.AutoScroll = False
            Me.PictureBox1.Size = Me.ClientSize
            Me.PictureBox1.SizeMode = PictureBoxSizeMode.Zoom
        Else
            Me.AutoScroll = True
            Me.PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
        End If
    End Sub

End Class



Public Class PictureBoxEx
    Inherits PictureBox

    Protected Overrides Sub OnPaint(ByVal pe As System.Windows.Forms.PaintEventArgs)
        If Me.Image IsNot Nothing AndAlso Me.SizeMode = PictureBoxSizeMode.Zoom Then
            ' SizeMode=Zoomのときは、Heightをあわせるために自分でImageを描画する
            Dim scale As Double = Me.Height / Me.Image.Height
            pe.Graphics.DrawImage(Me.Image, 0, 0, CInt(Me.Image.Width * scale), Me.Height)
        Else
            MyBase.OnPaint(pe)
        End If
    End Sub

End Class
返事が遅くなり申し訳ありません。

やじゅさん、H.K.R.さん、ありがとうございます。

H.K.R.さんの、ScrollableControlの継承でできそうですね。
やじゅさんの、SuspendLayoutを利用する方法もありかと思います。

時間がなく、今回はフォーム上にパネルを置き、その中にPictureBoxを配置して、
パネルをAutoScrollさせて、PictureBoxのサイズをコントロールさせることにより
実現させました。
お二方の方法は参考になりそうですので、テストし、今後、利用させていただこうかと思います。
ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板