- PR -

Closingメソッドで押されたボタンを判断したい

投稿者投稿内容
はの
会議室デビュー日: 2007/07/11
投稿数: 5
投稿日時: 2007-07-25 07:47
いつも拝見させていただいています。
前回は親切丁寧に教えてくださりありがとうございました。

環境:Windows xp / VS 2005 / C#

今回はClosingメソッドについて質問させていただきます。

フォームのOKボタン(Button1)と閉じるボタン(Button2)と、右上の×ボタンの
判断が出来るようなものはあるのでしょうか・・・?
OKボタンの時はそのままCloseをして
閉じるボタン、×ボタンを押された時は変更を確定するかの分岐を行いたいのです。
色々調べた結果、senderを使うと分かるというのを見つけたのですが
うまく行きません。

分かる方いらっしゃいましたら、ご助言の方よろしくお願いいたします。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-07-25 07:53
うまくいかない、の内容を知りたいところですが、Formが送られている、ということでしょう。

この場合、OKと閉じるについてはそれぞれのクリックイベントでフラグをセットする。×は、フォームのコンストラクタでフラグをセットする。かな
はの
会議室デビュー日: 2007/07/11
投稿数: 5
投稿日時: 2007-07-25 08:30
すばやい返答ありがとうございます。

引用:

Jittaさんの書き込み (2007-07-25 07:53) より:
うまくいかない、の内容を知りたいところですが、Formが送られている、ということでしょう。

この場合、OKと閉じるについてはそれぞれのクリックイベントでフラグをセットする。×は、フォームのコンストラクタでフラグをセットする。かな



説明不足で申し訳ありません。
はい、senderにうまくボタンの情報が入っていなくFormが送られてきています。
やはりフラグをセットするやり方のがいいのでしょうか?

コードはこんな感じです。(手打ちをしてしまったので打ち間違い等あるかもしれません)
//MessageResultの返す値で更新するかしないかの決定をしています。
private void Button1_Click(object sender,EventArgs e){
This.Close();
}
//2つのボタンとも同じ処理をしているので1つは省きます
private void Form1_Closing(object sender,ClosingEventArgs e){
if(senfer==Button1)
{
This.MessageResult = MessageResult.OK;
this.Close();
}
else
{
if(Combobox1.Text != 0)
{
if(MessageBox.Show("更新しますか?","確認",MessageBoxButtons.OKCanel) == MessageResult.OK)
{
This.MessageResult = MessageResult.OK;
this.Close();
}
else
{
This.MessageResult = MessageResult.Cancel;
this.Close();
}
}
}
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-07-25 09:22
引用:

はのさんの書き込み (2007-07-25 08:30) より:
はい、senderにうまくボタンの情報が入っていなくFormが送られてきています。



FormのClosingイベントはFormが発生させるイベントですので、
そのsenderにはFormにしか入ってきません。

よい方法かはわかりませんが、案の1つとして以下のような方法もあります。
FormのTagプロパティをフラグ代わりに使ってはいかがでしょうか。
Button1のClickイベントではTagプロパティにButton1オブジェクトを
Button2のClickイベントではTagプロパティにButton2オブジェクトをセットします。
Closingイベントでは、Tagプロパティを見てButton1、Button2が入っていれば
それぞれのボタンによるもの、nullなら×ボタンが押下されたものと判断します。

後、質問の本題とははずれますが、ソースコードを拝見しますと
いくつかまずそうな点が見受けられますのでコメントします。
(ソースコードは斜め読みしかしてませんので、該当しない場合は無視してください)

(1) Closingイベントの中でCloseメソッドを呼んでいるようですが、
ここでのthisはForm1自身ではないでしょうか?
Closeメソッドの呼び出しにより発生するClosingイベントの中でさらに
Closeメソッドを呼び出すのはまずいような・・・

(2) 更新しますか?というメッセージの表示の際、キャンセルされても、
this.Closeを呼び出して強制的に閉じようとしているようですが、
キャンセルした場合は閉じない方がよいのでは?
(要件・仕様次第かもしれませんが、一般的な動作としては違和感があります)


じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-07-25 09:32
引用:

はのさんの書き込み (2007-07-25 08:30) より:

やはりフラグをセットするやり方のがいいのでしょうか?


同じ方法なわけですが。

Form が閉じられた時の Action は System.Windows.Forms.DialogResult 列挙型を使うことで示すことができます。 ShowDialog メソッドでその Form を表示しているのであれば、DialogResult プロパティを設定するだけで Form が Close されます。 それ以外の場合は Form が閉じられないので DialogResult プロパティに値を設定したのち Close メソッドを呼び出せば良いです。

なぜこうするかというと、将来 ShowDialog メソッドによって呼び出された時に呼び出し元で結果を受け取るのが容易になるからです。

なお Form が閉じられることを示すイベントを利用する場合は Closing イベントではなく FormClosing イベントを使うようにしましょう。 これは .NET Framework 2.0 で新しく加わったイベントです。 Closing イベントは互換のために残っているだけです。 スレッド タイトルでは "Closing メソッド" と書かれていますが、Closing イベントが正しいです。

Button そのものが知りたいなら、最後に押下された Button の参照を保存しておけば良いです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2007-07-25 09:37
引用:

private void Form1_Closing(object sender,ClosingEventArgs e){
if(sender==Button1)
{
This.MessageResult = MessageResult.OK;
this.Close();
}


VS2005なのに"Form1_Closing"?と思いましたが、ひとつのイベントハンドラでまかなっているのでしょうか?
VS2005であればFormClosingイベントが使え、閉じられた理由を知ることができます。
http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.formclosingeventargs_members(VS.80).aspx
つまりXボタン(ユーザーの操作)で閉じられたことを知ることができます。
個別のボタンに関してはJittaさんの言われるようにボタン種別を表す列挙型を作ってクリック時に設定するとよいでしょう。
Form_Closingで閉じられた理由が
「ユーザーの操作」であればXボタン
「コード」であれば押されたボタンの判断
というようになるでしょう。
各ボタンの処理は次のようにシンプルですので、イベントハンドラを集約する必要は無いかなと思います。
コード:
this.ClickedButton = ClickedButton.Button1;
this.Close();

まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2007-07-25 09:40
#自己レス
引用:

引用:

private void Form1_Closing(object sender,ClosingEventArgs e){


VS2005なのに"Form1_Closing"?と思いましたが、ひとつのイベントハンドラでまかなっているのでしょうか?


ClosingEventArgsって無いよね?という理由です。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-07-25 10:52
引用:

まどかさんの書き込み (2007-07-25 09:40) より:

ClosingEventArgsって無いよね?という理由です。


おっと、気付かなかったですね。

コード:

    // Closing イベントのシグネチャ例
    private void Form1_Closing(System.Object sender, System.ComponentModel.CancelEventArgs e)

    // FormClosing イベントのシグネチャ例
    private void Form1_FormClosing(System.Object sender, System.Windows.Forms.FormClosingEventArgs e)


ですね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌

スキルアップ/キャリアアップ(JOB@IT)