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

処理中に表示する砂時計のカーソル

環境/言語:[XP C#]
分類:[.NET]

環境:XP、VS2010、C#3.0

あるフォームから別のフォームのオブジェクトを作り表示させる場合、表示されるまでの時間、カーソルを変更したいと思っています。

下記のページを参考にさせて頂きました。
http://dobon.net/vb/dotnet/form/cursorcurrent.html

やりたい事は、XFormのボタン押下時、YFormが起動するまでカーソルを変え、起動したらカーソルを元の形に変えたいと思っています。そこで下記の2つのコードを書きました。

問題は、一瞬カーソルが砂時計に変わるのですが、すぐに「I」のようなカーソルに戻ってしまいます。
どのように対応すれば問題が解決されるでしょうか?よろしくお願いします。

XFormのボタン
private void button_Click(object sender, EventArgs e)
{
//待機状態
Cursor.Current = Cursors.WaitCursor;
}

YFormのロード
private void YForm_Load(object sender, EventArgs e)
{
//元に戻す
Cursor.Current = Cursors.Default;
}


または、

XFormのボタン
private void button_Click(object sender, EventArgs e)
{
Cursor preCursor = Cursor.Current; //砂時計処理
Cursor.Current = Cursors.WaitCursor;

//YFormオブジェクト作成
}

YFormのロード
private void YForm_Load(object sender, EventArgs e)
{
//色々な処理

//最後に元に戻す
Cursor.Current = Cursors.Default;
}
Loadイベントの代わりにShownイベントを使えばどうでしょうか?
> 下記のページを参考にさせて頂きました。
> http://dobon.net/vb/dotnet/form/cursorcurrent.html

上記ページの「Cursor.Currentプロパティによる方法」には

> ただしマウスイベントの待機が再開されることによってカーソルが解除されますので、
> Cursors.Defaultで元に戻さなくても、大抵の場合は問題なく元に戻ります。

とあります。
その下の例の2行だけをボタンのクリックイベントにコピペすると分かると思いますが、

'待機状態
Cursor.Current = Cursors.WaitCursor
'5秒間停止する
System.Threading.Thread.Sleep(5000)

↑これだけ

イベント終了時に勝手に元に戻ります。

なので、上記ページの「Control.Cursorプロパティによる方法」を
参考にすれば良いと思います。
Hongliang さん、anさん

ご回答ありがとうございます。お教え頂きましたように、コードを書きなおしてみました。
しかしながら、下記の現象です。

1.XFormボタンを押下
2.XForm 非表示になる(YFormはモーダルダイアログ)
3.カーソルは「I」のまま
4.YFormロード(ここで色々な処理をしているので、YFormが表示されるまでに2秒くらいあります)
5.YForm表示
6.YForm閉じる
7.カーソルが砂時計になる
8.XFormが再表示される

2〜5までの間、カーソルが砂時計に変わっていてもらいたいのですが、どこを修正すればよろしいでしょうか?お手数おかけしまして申し訳ありません。

//////////////////////////////////////////////////////////////////////
//XFormのボタン
//////////////////////////////////////////////////////////////////////
private void button_Click(object sender, EventArgs e)
{
//待機状態
this.Cursor = Cursors.WaitCursor;
}

//////////////////////////////////////////////////////////////////////
//YFormのロード
//////////////////////////////////////////////////////////////////////
private void YForm_Load(object sender, EventArgs e)
{
//元に戻す
this.Cursor = Cursors.Default;
}

//////////////////////////////////////////////////////////////////////
//YFormのshownイベント
//////////////////////////////////////////////////////////////////////
private void YForm_Shown(object sender, EventArgs e)
{
//元に戻す
this.Cursor = Cursors.Default;
}
■No32135に返信(たけしさんの記事)
> 2.XForm 非表示になる(YFormはモーダルダイアログ)

this.Cursor は見ての通りで、this(自分自身のフォーム)に対して行うので、
非表示にするのであればダメですね。

今回の前提で対応する方法は自分の引き出しにはありませんでした。


前提が崩れてしまうので回答というわけではありませんが、
自分にはこれくらいしか思い浮かびません。

1.XFormボタンを押下
2.カーソルを砂時計へ
3.YFormロード処理(※1)
4.XForm 非表示
5.YForm表示
6.YForm閉じる
7.カーソルを元へ(※2)
8.XFormを再表示

※1
YFormのLoadイベントではなく、コンストラクタか独自のメソッドで行う。
YFormのLoadイベントだと、ShowDialogメソッド実行時に発生するので、
ロード後に非表示が行えないので。

※2
this.Cursor = Cursors.WaitCursor;
を使った場合のみ。
Cursor.Current = Cursors.WaitCursor;
の場合は必要ない。

注意点としてはカーソルが砂時計になったとしても、
XFormは触れてしまうので、制御が必要ですが、
XFormのEnabledをFalseにしてしまうと、
砂時計ではなくなってしまうようです。
ボタン等を個別でEnabledをFalseにする等の工夫が必要です。
■No32135に返信(たけしさんの記事)
> 4.YFormロード(ここで色々な処理をしているので、YFormが表示されるまでに2秒くらいあります)
このいろいろな処理をバックグラウンドワーカーに任せ
バックグラウンドワーカーの処理が終了したらカーソルを戻すとよいと思います。
anさん

ご回答ありがとうございました。アドバイス頂きましたように、コンストラクタでカーソルの設定を行いました。

前回の私のコードでは砂時計が一瞬で消えてしまいましたが、今回はフォームがロードしてきたらカーソルは砂時計になっていました。

ただ、YForm表示の時に、データベースに接続してDataTableにデータを読み込んでグリッドビューに表示するという処理をしています。かなりのデータ量になるので、フォームが表示されるまで数秒、カーソルは「I」のままです。フォームが表示されてくると砂時計にかわります。

なので、私が求めているものは難しそうです。shuさんからお教え頂いたBackgroudworkerで試してみたいと思います。ありがとうございました。

//////////////////////////////////////////////////////////////////////
//XFormのボタン
//////////////////////////////////////////////////////////////////////
private void button_Click(object sender, EventArgs e)
{
//待機状態
this.Cursor = Cursors.WaitCursor;
}

//////////////////////////////////////////////////////////////////////
//YFormのコンストラクター
//////////////////////////////////////////////////////////////////////
public YForm()
{
this.Cursor = Cursors.WaitCursor;
InitializeComponent();
}
//////////////////////////////////////////////////////////////////////
//YFormのロード
//////////////////////////////////////////////////////////////////////
private void YForm_Load(object sender, EventArgs e)
{

}

//////////////////////////////////////////////////////////////////////
//YFormのshownイベント
//////////////////////////////////////////////////////////////////////
private void YForm_Shown(object sender, EventArgs e)
{
//元に戻す
this.Cursor = Cursors.Default;
}

shuさん

BackgroudWorkerについては使ったことがないので、一度試してみます。

ご回答頂きました皆様、ありがとうございました。
解決済み!

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