【.Net手抜きの氾濫】スクロールバーの位置や操作の最大値は手抜き仕様

スクロールバーの位置がおかしい?

スクロールバーの位置 = コントロールの大きさ(Width,Height) - スクロールバーの大きさ

で計算していたので

スクロールバーの位置 = コントロールのクライアント領域の大きさ(ClientSize) - スクロールバーの大きさ

に変更した。
本来なら、デスクトップのデザインが変更になったら、クライアント領域の大きさが変わるので、全コントロールに通知しなければいけないのだが、

Windows 32APIで新設されたデスクトップのデザイン通知メッセージが.Netには無い。

ま、気にしなければいらないかな。(大笑
それでも、まだ最大までスクロールしてもバーの大きさの半分ぐらいスライドできない。
ググって見ると、

.NET FrameworkのSystem.Windows.Forms.ScrollBar.Valueプロパティの値はマウス操作ではMaximum-LargeChange+1までしか行かない

という大笑いネタを発見。
その通りにするとピッタリ。
//但し、スクロールバーを操作時の最大値はMaximum-LargeChange+1までなので・・・
sbH.Maximum = this.Image.Size.Width – sbH.Width + (sbH.LargeChange + 1);
なぜ、そうなのかと云えば、
このLargeChangeを丁度良い感じにすると最後まで増やした時に、最大値を超える問題が発生するので安易な補正をかけたとした思えない。
しかも、ドット単位でスクロールをするか画面上のGridのセルコントロールの配置サイズでスクロールするかで、また考え方を変えなくてはいけない。
気持ちよくスクロールするには、
どうすればよいのか色々

考えて使って直して考えて使って直して考えて使って直して

の繰り返し。
しかもそれは画面の内容次第でコロコロ変わる。

iPhoneの気持ちの良さは

『頑固で偏屈な石頭だらけのプレゼンテーション』を一発で通る内容に終始しているから、

使ってみると「さくっと気持ちの良さが伝わる」が・・・

それは副作用でしかなく、本当に使いやすいかどうかは別腹なのだ。

もちろん、「第一印象」は重要なことだが・・・

閑話休題。
確かに鉄板のGUIなんて存在しない。
しかし、MSやスクエニが云うと
『俺ん家には無理!』
と云っているだけでしかないのもまた事実である。(大笑
【修正後のソース】
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Custom.Control
{
class ccPictureBox : PictureBox
{
//画像が大きい時に表示する
VScrollBar sbV;
HScrollBar sbH;
float dx = 0;
float dy = 0;
///
/// コンストラクター
///
public ccPictureBox()
{
sbV = new VScrollBar();
sbV.Parent = this;
sbV.Scroll += sbV_Scroll;
sbV.Visible = false;
sbH = new HScrollBar();
sbH.Parent = this;
sbH.Scroll += sbH_Scroll;
sbH.Visible = false;
this.DragDrop += new System.Windows.Forms.DragEventHandler(myDragDrop);
this.DragEnter += new System.Windows.Forms.DragEventHandler(myDragEnter);
ChkScrollBar();
}
///
/// 横スクロール時
///
//////void sbH_Scroll(object sender, ScrollEventArgs e)
{
dx = e.NewValue;
this.Invalidate();
}
///
/// 縦スクロール時
///
//////void sbV_Scroll(object sender, ScrollEventArgs e)
{
dy = e.NewValue;
this.Invalidate();
}
///
/// 描画時
///
///protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
g.TranslateTransform(-dx, -dy);
GraphicsState bk = g.Save();
base.OnPaint(e);
g.Restore(bk);
}
///
///
///
[Bindable(true)]
[Localizable(true)]
public new Image Image
{
get
{
return base.Image;
}
set
{
base.Image = value;
ChkScrollBar();
}
}
///
///
///
[Bindable(true)]
[Localizable(true)]
public new Size Size
{
get
{
return base.Size;
}
set
{
base.Size = value;
ChkScrollBar();
}
}
[DefaultValue(false), Browsable(true), Description(“コントロールが、ユーザがドラッグしたデータを受け入れできるかを示します。”), Category(“動作”)]
public override bool AllowDrop { get; set; }
///
/// ドラッグ処理のイベントハンドラー
///
//////private void myDragEnter(object sender, DragEventArgs e)
{
//ファイルならOKにしておく。
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
}
///
/// ドラッグ処理のイベントハンドラー
///
//////private void myDragDrop(object sender, DragEventArgs e)
{
//ファイルなら
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
// ドラッグ中のファイルなどを取得
string[] drags = (string[])e.Data.GetData(DataFormats.FileDrop);
string fileName = null;
foreach (string d in drags)
{
if (!System.IO.File.Exists(d))
{
// ファイル以外であれば読み飛ばす。
continue;
}
fileName = d;
}
if (fileName != null)
{
try
{
this.Image = Image.FromFile(fileName);
}
catch (Exception ex)
{
MessageBox.Show(“【” + fileName + “】” + ex.Message);
}
e.Effect = DragDropEffects.Copy;
ChkScrollBar();
}
}
}
///
/// スクロールバーを表示するかどうかチェックし
/// 表示する際には位置や設定範囲を調整する
///
///
private bool ChkScrollBar()
{
bool rc = false;
if (this.Image != null)
{
bool showV = (this.Height < this.Image.Size.Height);
bool showH = (this.Width < this.Image.Size.Width);
rc = showH | showH;
//
if (showV)
{
sbV.Top = 0;
sbV.Left = this.ClientSize.Width – sbV.Width;
//両方表示する場合、横スクロールバーの高さ分小さくする
sbV.Height = this.ClientSize.Height – (showH ? sbH.Height : 0);
//大雑把な操作はスクロールバーの高さ分
sbV.LargeChange = sbV.Height;
//範囲の補正
//最大値=(画像の高さ)-(縦スクロールバーの高さ)
//但し、スクロールバーを操作時の最大値はMaximum-LargeChange+1までなので・・・
sbV.Maximum = this.Image.Size.Height – sbV.Height + (sbV.LargeChange + 1);
sbV.Visible = true;
}
else
{
sbV.Visible = false;
}
if (showH)
{
sbH.Top = this.ClientSize.Height – sbH.Height;
sbH.Left = 0;
//両方表示する場合、縦スクロールバーの幅分小さくする
sbH.Width = this.ClientSize.Width – (showV ? sbV.Width : 0);
//大雑把な操作はスクロールバーの幅分
sbH.LargeChange = sbH.Width;
//範囲の補正
//最大値=(画像の幅)-(横スクロールバーの幅)
//但し、スクロールバーを操作時の最大値はMaximum-LargeChange+1までなので・・・
sbH.Maximum = this.Image.Size.Width – sbH.Width + (sbH.LargeChange + 1);
//
sbH.Visible = true;
}
else
{
sbH.Visible = false;
}
}
return rc;
}
}
}
// EOF.




コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA