none
値の変更有無を取得する方法 RRS feed

  • 質問

  •  

    WEB画面上に配置したボタンを押されたタイミングで、WEB画面上に存在するコントロール

    (テキストボックス、ドロップダウンボックス等)の値に変更があったかどうかを簡単に取得する

    方法があれば教えていただきたいです。

    自分では、地道にコントロール一つ一つのValueをつき合わせていく方法くらいしか思いつきません。

     

    何か良い方法がありましたら、ご教授ください。よろしくお願いします。
    2007年8月27日 6:55

回答

  •  EI1207 さんからの引用

    「適切にビューステートを使っていれば」とは、どのような意味でしょうか?
    もしかして、その「適切にビューステートを使っていれば」画面上の
    コントロールの値が変更されるとPageクラス等の親コントロールで
    Changedイベントを拾えるってことですか?

    適切というか、ViewState が on だと、Postback が発生した時に変更されているコントロールの Changed イベントが発生します。

     

     EI1207 さんからの引用

    Changedイベントすべてに、一行程度とは思いますが、変更有りフラグを
    設定する処理をコーディングするのが無駄に感じました。

     

    何らかの条件で、対象のコントロールを絞り込めるならば、Page の OnInit にてループで設定するとよいのではないでしょか。

    たとえば、「すべてのTextBox、ただし ID=YおうrNameTextBox は除く」というような条件で絞り込めるなら、

     

    Code Snippet

        // 変更のあったコントロール一覧を保存する
        private System.Collections.Generic.List<TextBox> changedTextBoxs
            = new System.Collections.Generic.List<TextBox>();

     

        protected void Page_Load(object sender, EventArgs e)
        {
            // Changed イベントを再帰的に設定する
            InstallChangedEventHandler(this.Controls);
        }

     

        private void InstallChangedEventHandler(ControlCollection coll)
        {
            foreach (Control c in coll)
            {
                // TextBox かつ ID が YourNameTextBox ではないものが対象
                if ((c is TextBox) && (c.ID != "YourNameTextBox"))
                {
                    (c as TextBox).TextChanged += this.TextBox_Changed;
                }
                else if (c.Controls.Count > 0)
                {
                    // コンテナの場合、再帰的に調査する
                    InstallChangedEventHandler(c.Controls);
                }
            }
        }

     

        private void TextBox_Changed(object sender, EventArgs e)
        {
            // 変更されたコントロールのリストを対象として記録する
            this.changedTextBoxs.Add(sender as TextBox);
        }

     

        protected void CancelBtnClick(object sender, EventArgs e)
        {
            // キャンセルボタンが押された
            foreach (TextBox t in this.changedTextBoxs)
            {
                // 変更のあったテキストボックスの内容を書き換える
                t.Text = "(modified)";
            }
        }

     

     

    こんなかんじで、TextBox が何個あっても関係なく、変更された一覧を得ることができます。
     
    2007年8月29日 23:17

すべての返信

  • すみません、上記に対しての補足ですが、

     

     ・変更の有無は「どのコントロールに」とか「どんな」という変更情報は必要ありません。

    単に画面上のコントロールのいずれかに値の変更があったかどうかを取得したいです。

     

     ・取得できるのであればサーバー上、クライアント上のどちらでもかまいません。

     

    以上、よろしくお願いいたします。

     

    2007年8月27日 7:17
  • 何故それがしたいんでしょうか?
    とりあえず、適切にビューステートを使っていれば、変更系のイベントが発生しますが。

     

    2007年8月27日 7:39
  •  

    囚人さん、早速の返信ありがとうございます。

     

     囚人 さんからの引用
    何故それがしたいんでしょうか?

    値の変更有無を取得したい理由は、画面上に「キャンセル」ボタンを配置し、
    その「キャンセル」ボタンがクリックされた時点で他のコントロールの値に
    変更があった場合に限り「変更が失われます。よろしいですか?」的な
    メッセージ出力を実現したいからです。

     

     囚人 さんからの引用
    とりあえず、適切にビューステートを使っていれば、変更系のイベントが発生しますが。

    自分の勉強不足で申し訳ありませんが、囚人さんの言われている

    「適切にビューステートを使っていれば」とは、どのような意味でしょうか?
    もしかして、その「適切にビューステートを使っていれば」画面上の
    コントロールの値が変更されるとPageクラス等の親コントロールで
    Changedイベントを拾えるってことですか?

    例えば、各コントロールのChangedイベント等で変更有りフラグを立て、
    「キャンセル」ボタン押下時に変更有りフラグで変更有無を確認する
    という方法も考えたのですが、現在、画面上のコントロールがかなり多く、
    さらに画面数も多いシステムを作っており、それらの各コントロールの
    Changedイベントすべてに、一行程度とは思いますが、変更有りフラグを
    設定する処理をコーディングするのが無駄に感じました。
    ですので、もし囚人さんのおっしゃられている方法が上記で自分が勝手に
    解釈した親コントロールで・・・ということであれば是非コーディング例
    もしくは、サンプルページ等を教えて頂きたいです。


    だらだらとした説明で申し訳ありませんが、理解できましたら
    返信いただきたいです。よろしくお願いします。

    2007年8月27日 8:39
  •  EI1207 さんからの引用

    「適切にビューステートを使っていれば」とは、どのような意味でしょうか?
    もしかして、その「適切にビューステートを使っていれば」画面上の
    コントロールの値が変更されるとPageクラス等の親コントロールで
    Changedイベントを拾えるってことですか?

    適切というか、ViewState が on だと、Postback が発生した時に変更されているコントロールの Changed イベントが発生します。

     

     EI1207 さんからの引用

    Changedイベントすべてに、一行程度とは思いますが、変更有りフラグを
    設定する処理をコーディングするのが無駄に感じました。

     

    何らかの条件で、対象のコントロールを絞り込めるならば、Page の OnInit にてループで設定するとよいのではないでしょか。

    たとえば、「すべてのTextBox、ただし ID=YおうrNameTextBox は除く」というような条件で絞り込めるなら、

     

    Code Snippet

        // 変更のあったコントロール一覧を保存する
        private System.Collections.Generic.List<TextBox> changedTextBoxs
            = new System.Collections.Generic.List<TextBox>();

     

        protected void Page_Load(object sender, EventArgs e)
        {
            // Changed イベントを再帰的に設定する
            InstallChangedEventHandler(this.Controls);
        }

     

        private void InstallChangedEventHandler(ControlCollection coll)
        {
            foreach (Control c in coll)
            {
                // TextBox かつ ID が YourNameTextBox ではないものが対象
                if ((c is TextBox) && (c.ID != "YourNameTextBox"))
                {
                    (c as TextBox).TextChanged += this.TextBox_Changed;
                }
                else if (c.Controls.Count > 0)
                {
                    // コンテナの場合、再帰的に調査する
                    InstallChangedEventHandler(c.Controls);
                }
            }
        }

     

        private void TextBox_Changed(object sender, EventArgs e)
        {
            // 変更されたコントロールのリストを対象として記録する
            this.changedTextBoxs.Add(sender as TextBox);
        }

     

        protected void CancelBtnClick(object sender, EventArgs e)
        {
            // キャンセルボタンが押された
            foreach (TextBox t in this.changedTextBoxs)
            {
                // 変更のあったテキストボックスの内容を書き換える
                t.Text = "(modified)";
            }
        }

     

     

    こんなかんじで、TextBox が何個あっても関係なく、変更された一覧を得ることができます。
     
    2007年8月29日 23:17
  • K.Takaokaさん親切な回答ありがとうございます。

    返信遅くなってすみませんでした。

     

    K.Takaokaさんの教えてくださったコードを元に解決することが出来ました。

     

    本当にありがとうございました。

    2007年9月4日 2:03