スクロール処理
ウィンドウスクロールバー
ウィンドウの範囲を超えたドキュメントを表示したいという場合
通常は、ウィンドウの右と下部に垂直と水平のスクロールバーを付加します
実は、このスクロール処理というのは想像以上に複雑になっています
ユーザーがスクロールバーに対する入力を行うと、このイベントを処理し
スクロールバーの移動範囲を計算して、ドキュメントの描画する位置を決定します
しかし、.NET ではこれらの処理の大部分がカプセル化されています
Form クラスは System.Windows.Forms.ScrollableControl を継承しています
このクラスは、コントロールがスクロール可能になる基本機能を持っています
Object
MarshalByRefObject
Component
Control
ScrollableControl
public class ScrollableControl : Control
Form クラスのように、このクラスを継承しているコントロールは
このクラスの持つ特定のプロパティを設定することで、スクロールバーを付加できます
公開コンストラクタは、引数無しのデフォルトコンストラクタのみが定義されています
スクロールを可能にするには、まずはそれを許可する必要があります
ScrollableControl.AutoScroll プロパティを用いてこれを設定できます
public virtual bool AutoScroll {get; set;}
このプロパティが true であればスクロールを許可し
そうでなければ false を指定します。このプロパティはデフォルトで false です
次に、スクロールの最小範囲を指定しなければなりません
これは ScrollableControl.AutoScrollMinSize プロパティを使います
public Size AutoScrollMinSize {get; set;}
このプロパティには、スクロール範囲となる最小の幅と高さを Size オブジェクトで指定します
コントロールがこれ以下のサイズになると、自動的にスクロールバーが表示されます
たったこれだけの作業でウィンドウにスクロールバーを付けることができます
ただし、スクロールバーが動かされた時の再描画の位置が問題です
スクロールバーが動かされた分、表示するドキュメントも移動する必要があります
スクロール後に正しく描画するには、移動した原点を取得する必要があります
ScrollableControl.AutoScrollPosition プロパティは
原点の位置を示す Point オブジェクト表します
public Point AutoScrollPosition {get; set;}
これはどういうことかというと、例えば垂直するロールバーを下に移動させると
原点は上に、すなわちマイナス方向に移動するということになります
そして、コントロールは現在描画されているドキュメントを上に移動しさせ
コントロールのクライアント領域下部を無効化して新しく再描画します
このとき、OnPaint() メソッドは座標を上手く処理し、適切な対応をしなければなりません
バーを動かしたのに、再描画領域が同じ図を描画した場合は奇妙な結果に終わります
AutoScrollPasition が返した原点の位置を上手に使う必要があります
using System.Windows.Forms;
using System.Drawing;
class WinMain : Form {
Image img;
public static void Main(string[] args) {
WinMain win = new WinMain();
win.img = new Bitmap(args[0]);
win.AutoScroll = true;
win.AutoScrollMinSize = new Size(win.img.Width , win.img.Height);
Application.Run(win);
}
override protected void OnPaint(PaintEventArgs e) {
Point pt = AutoScrollPosition;
e.Graphics.DrawImage(img , pt.X , pt.Y);
Text = "X = " + pt.X + " : Y = " + pt.Y;
}
}
このプログラムは、コマンドライン引数で指定した静止画を表示するというものですが
ウィンドウがイメージのサイズより小さくなると、スクロールバーを表示します
また、タイトルバーに AutoScrollPosition の値も描画します