none
メインフォームから次々に2つのフォームを開いてメインフォームに戻るとき RRS feed

  • 質問

  • A→B→C とフォームを開いていって,「フォームCからフォームAに戻るとき」に,タスクバーにフォームAのアイコンが表示されているだけでフォームA自体は表示されないでいることを解決したくてお尋ねします。

    3つのフォームに親子関係は設定していません。どうぞよろしくおねがいします。

    A: frm0Nenu  B: frm12msgKaihi    C:  frm12groupKaihi 

    AからBを開くとき

    frm12msgKaihi frmKaihi = new frm12msgKaihi();
    //frmKaihiからfrmMainを参照できるようにする
    frmKaihi.frmMain = this;
    frmKaihi.Show();

    BからCを開くとき

    //frm2からfrmHomeを参照できるようにする  
    fm2.frmHome = this;
    fm2.Show();
    this.Close();
    Cを閉じる(Aを表示)とき

    this.Close();


    zen73

    2010年8月9日 2:26

回答

  • 外池です。その現象、私も出くわしました!! 最後にCを閉じるときに、AにFocus()する操作をすればOKかと思います。以下のようなコードで、いい感じに動きますが、いかがでしょう?

     public partial class MainForm : Form {
     private frmDialog _dlg;
     
     public MainForm() {
      InitializeComponent();
     }
    
     private void btnShow_Click(object sender, EventArgs e) {
      this.Enabled = false;
      _dlg = new frmDialog();
      _dlg.Owner = this;
      _dlg.Show();
     }
     }
    

     

     public partial class frmDialog : Form {
     public frmDialog() {
      InitializeComponent();
     }
    
     private void btnOK_Click(object sender, EventArgs e) {
      Owner.Enabled = true;
      Owner.Focus();
      this.Close();
     }
     }
    

     

    ----------------以下、Microsoft殿へ

    4回ほど、投稿に失敗して、その都度、全文書き直しです。編集したら、ページ全体のHTMLが現れたりもしました。極めて使いにくいし、投稿する気力を殺がれます。善処を求めます。


    (ホームページを再開しました)
    • 回答としてマーク zen73 2010年8月9日 23:33
    • 回答としてマークされていない zen73 2010年8月9日 23:34
    • 回答としてマーク zen73 2010年8月9日 23:40
    2010年8月9日 22:24

すべての返信

  • AからBを開いたときにAはどのような状態なのでしょうか? MDIでしょうか、SDIでしょうか? フォームの遷移は不定でしょうか? フォームの遷移の仕方によっては、どこかにstaticなクラスでフォームのインスタンスを管理した方がいいかもしれません。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年8月9日 3:01
    モデレータ
  • trapemiyaさんには以前より数多くのことを教えていただいて出納簿4というアプリケーションを完成させることができ,お陰さまで千人を超える方々に使っていただいています。年老いたじじいの未熟なアプリケーションでも,少しは世間の役に立っているのかと思うと嬉しい限りです。改めてtrapemiyaさんはじめお教えいただいた皆さんに感謝申します。

    対個人的なことを申しましたがお許し願います。

    >AからBを開いたときにAはどのような状態なのでしょうか?

    開いたBの後ろに完全にかくれています。

    >MDIでしょうか、SDIでしょうか? 

    SDIです。

    >フォームの遷移は不定でしょうか?

    「不定」の意味する事柄をりかいできないます。,30を超えるフォーム(中にはフォームBのようにmessageBoxのような役割を果たすものがありますが)のほとんどは,AからDを開きその後Aに戻ってDを閉じるといった遷移をするものがほとんどです。

    ご指導のほど,よろしくお願いいたします。


    zen73
    2010年8月9日 4:10
  • 外池と申します。「状態遷移図」、というものを描いて考えると整理しやすかったりします。一度トライしてみてください。

    さて、大抵の場合、メインフォームから、ダイアログを表示して、元に戻るという処理とのことですが、これは、メインフォームが表示された状態「A」から、ダイアログ「Bi」が表示された状態へ、移って戻るという2つの状態間の往復のようなイメージになります。

    で、今回のご質問は、「A」の状態から、フォーム「C」が表示された状態へ移って、さらに、フォーム「D」が表示された状態へ移って、「A」へ戻るという、3角形のような状態変化のようにお見受けしますが、正しいでしょうか?

    あと、いずれの場合であっても、フォームAは、表示されているべき? 表示が消えているべき? どちらでしょう? 「隠れている」というご説明はじゃっかん紛らわしいです。覆いかぶさっているフォームを横にずらしたときは、下のフォームAは見えるべき? 見えないべき? どちらでしょうか?

    意図されている動作を改めて少し厳密にご説明頂けると回答もつきやすいかと思います。


    (ホームページを再開しました)
    2010年8月9日 4:43
  • 外池です。極端に簡単化していますが、次のようなやりかたじゃマズイんでしょうか?

      public partial class MainForm : Form {
        public MainForm() {
          InitializeComponent();
        }
        private void btnReciprocal_Click(object sender, EventArgs e) {
          FormB frm1 = new FormB();
          frm1.ShowDialog();
          frm1.Dispose();
        }
        private void btnTriangle_Click(object sender, EventArgs e) {
          FormC frm1 = new FormC();
          frm1.ShowDialog();
          frm1.Dispose();
          FormD frm2 = new FormD();
          frm2.ShowDialog();
          frm2.Dispose();
        }
      }
    

    (ホームページを再開しました)
    2010年8月9日 5:01
  • 対個人的なことを申しましたがお許し願います。

    お力になれればうれしく思います。ご質問に回答することは私の勉強になりますし、いっしょに問題を解決する気持ちでいつも書き込んでいますので、どうぞ忌憚なくお付き合いいただければと思います。

    開いたBの後ろに完全にかくれています。

    外池さんも言われてますが、隠れるというのは何を意図されているのか掴みかねています。普通に考えれば、Aは表示された状態でBの後ろに隠れているということでよろしいでしょうか?ただ、であればCを閉じるだけでAが出てくると思うのですが・・・

    Aのみ表示
          ↓
    AとBが表示・・・BがAの上に表示されている。
          ↓
    AとCが表示・・・CがAの上に表示されている。
          ↓
    Aのみ表示・・・Cが閉じたため、Aのみ残った。

    「不定」の意味する事柄をりかいできないます。,30を超えるフォーム(中にはフォームBのようにmessageBoxのような役割を果たすものがありますが)のほとんどは,AからDを開きその後Aに戻ってDを閉じるといった遷移をするものがほとんどです。

    ユーザーのオペレートによって、A -> B -> C になったり、A -> B2 -> D になったりと遷移が一定でない意味で不定という言葉を使いました。例えば、必ず A -> B -> Cと定まって遷移するのであれば、不定な場合に比べて単純に実現できます。

    いずれにしましても、

    タスクバーにフォームAのアイコンが表示されているだけでフォームA自体は表示されないでいることを解決したくてお尋ねします。

    と言われている意味がまだはっきりイメージできないでいます。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年8月9日 5:37
    モデレータ
  • 外池さんにも以前にずいぶんと教えていただきました。そして,今回も「質問の意図を捉え難い質問」にまでもご返信をいただき本当にありがたく思います。

    私の解決したいと思っている状況についてもう一度説明させて頂きます。

    >タスクバーにフォームAのアイコンが表示されているだけでフォームA自体は表示されないでいることを解決したくてお尋ねします。 と言われている意味がまだはっきりイメージできないでいます

    プログラミングの最中,気分転換をしたいときによくマージャンゲームをしますが最小化ボタンを押したとき画面に表示されていた牌が表示されなくなり,タスクバーをクリックするとまた以前のように牌が表示されますね。 このようにメインフォームAが最小化ボタンが押された状態になり,表示されるはずのたくさん並んだボタンを表示させるためにはタスクバーのアイコンをクリックせねばならぬ状況です。

    あと、いずれの場合であっても、フォームAは、表示されているべき? 表示が消えているべき? どちらでしょう?

     「表示されているべき」と思ってしまったというのが正解です。アプリケーションを起動してAを表示した後に収入科目と支出科目の大科目とそれに対する小科目それぞれの数および名称等々を配列に取り込みますが,それを他のフォームから参照するためには,フォームAは「表示されているべき」と思い込んでいたのでした。フォームAの表示は消えていたほうがいいのです。

    覆いかぶさっているフォームを横にずらしたときは、下のフォームAは見えるべき? 見えないべき? どちらでしょうか?
    見えないほうがいいのです。たくさんのボタンが並んでいますから,それを押されてしまったときの対処を考えるなんて気が遠くなってしまいます。みてボタンを押されないための対策としてフォームのサイズを画面いっぱいに拡げることやフォームの3つのボタンを表示しないなどの対策をとっています。
    Aのみ表示      ↓ AとBが表示・・・BがAの上に表示されている。      ↓ AとCが表示・・・CがAの上に表示されている。      ↓ Aのみ表示・・・Cが閉じたため、Aのみ残った。
    このとおりなのですが,残ったAを見るためにはタスクバーのアイコンをクリックしなければならないことが問題なのです。
    zen73
    2010年8月9日 7:24
  • つまりAは最小化しているということでしょうか? 通常はそのような状態にはなりませんが、どのようなコードを書かれていますか?


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年8月9日 9:02
    モデレータ
  • 外池です。すいません、投稿しようとして失敗してしまい。かなり書いたものが失われてしまいました。要点だけ再度書きます。

    いくつかの問題が出てきていますので、整理した方がよさそうです。1)フォームAが勝手に最小化されている問題、2)これが解決したとして、別のフォームを表示しているときにフォームAを操作できなようにする方法、3)そして、フォームAから、別のフォーム、さらに別のフォームと三角形の状態遷移を実現する方法です。

    1)についてはtrapemiyaさんが仰るように、何かおかしな操作をしてしまっているように思いますので、再点検してください。

    2)についてはShowDialogすればモーダルモードで他のフォームが開いて、元のフォームは操作できなくなります。また、Showする場合でも元のフォームのEnabledをfalseにすれば操作できなくなります。


    (ホームページを再開しました)
    2010年8月9日 12:51
  • すみません。trapemiyaさんと外池さんにはお詫びを申さねばいけません。

    私のそそっかしさとかボケ頭の表出というか,質問そのものが意味をなさないものでした。お二方には貴重なお時間を浪費させててしまい申し訳なく思います。質問すべきことは次のことでした。

    Aのみ表示
          ↓
    AとBが表示・・・BがAの上に表示されている。
          ↓
    AとCが表示・・・CがAの上に表示されている。
          ↓
    Aのみ表示・・・Cが閉じたため、Aのみ残った。

    Aはしっかりと見えてはいるのですが,Aの上に実行中という編集画面がでてしまうのです。

    私の質問は「デバッグ中には編集画面がでないようにしたい」ということでした。

     


    zen73
    2010年8月9日 18:32
  • 外池です。その現象、私も出くわしました!! 最後にCを閉じるときに、AにFocus()する操作をすればOKかと思います。以下のようなコードで、いい感じに動きますが、いかがでしょう?

     public partial class MainForm : Form {
     private frmDialog _dlg;
     
     public MainForm() {
      InitializeComponent();
     }
    
     private void btnShow_Click(object sender, EventArgs e) {
      this.Enabled = false;
      _dlg = new frmDialog();
      _dlg.Owner = this;
      _dlg.Show();
     }
     }
    

     

     public partial class frmDialog : Form {
     public frmDialog() {
      InitializeComponent();
     }
    
     private void btnOK_Click(object sender, EventArgs e) {
      Owner.Enabled = true;
      Owner.Focus();
      this.Close();
     }
     }
    

     

    ----------------以下、Microsoft殿へ

    4回ほど、投稿に失敗して、その都度、全文書き直しです。編集したら、ページ全体のHTMLが現れたりもしました。極めて使いにくいし、投稿する気力を殺がれます。善処を求めます。


    (ホームページを再開しました)
    • 回答としてマーク zen73 2010年8月9日 23:33
    • 回答としてマークされていない zen73 2010年8月9日 23:34
    • 回答としてマーク zen73 2010年8月9日 23:40
    2010年8月9日 22:24
  • >外池です。その現象、私も出くわしました!! 

    お聞かせ頂いて安心しました。お示しいただいたコードを早速使わせていただくこととします。

    私へのご回答をくださるためにかなりお手間をとらせたご様子,外池様のお気持に心より感謝申します。

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


    zen73
    2010年8月9日 23:40
  • ----------------以下、Microsoft殿へ
    4回ほど、投稿に失敗して、その都度、全文書き直しです。編集したら、ページ全体のHTMLが現れたりもしました。極めて使いにくいし、投稿する気力を殺がれます。善処を求めます。
    それは、意見・要望フォーラムに書いてください。
    特定の質問スレッドでこそっと書くものではないと思います。
    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2010年8月10日 2:50
    モデレータ
  • 外池です。

    Focus()すれば良い、というのが一般論かどうか自分でもよくわからなくなってきました。自分なりにパターン化して整理するつもりで書いてみたところ、末尾のとおりのコードで問題なく動きました。Focus()メソッドは特に使っていません。

    基本的な考え方は以下の通りです。

    MainFormが全体の動きを制御するものでzen73さんのフォームAに相当します。1つのダイアログしか出さないのか、2つのダイアログを連続して出すのか、そのあたりの制御もすべてMainFormで行っています。他のフォーム(DialogAやDialogB)をShowしています。ShowDialogではありません。このため、他のフォームが閉じられたことをイベントで受け取るようにしています。

    DialogAには、btnOKとbtnCancelの2つのボタンが載っていますが、どちらのClickイベントも同一のハンドラbtn_Clickで受け取っています。btnCancelが押されたときはReturnCode=1を返すものとし、そうでなければ、ReturnCode=0を返します。

    DialogBには、btnOKだけが載っています。ReturnCodeは常に0です。

    DialogAに対してOKすれば続けてDialogBへ、最後にMainFormに戻ります。
    DialogAに対してCancelすれば、すぐにMainFormに戻ります。

    デザインパターンの参考にして頂ければ幸いです。

      public partial class MainForm : Form {
        public MainForm() {
          InitializeComponent();
        }
        private void btnShow_Click(object sender, EventArgs e) {
          this.Enabled = false;
          this.Text = "Asking...";
    
          DialogA _dlg = new DialogA();
          _dlg.FormClosed += DialogAClosed;
          _dlg.Show();
        }
        public void DialogAClosed(Object sender, FormClosedEventArgs e) {
          if(((DialogA)sender).ReturnCode == 1) {
            this.Text = "DialogA Cancel";
            this.Enabled = true;
            return;
          }
          DialogB _dlg = new DialogB();
          _dlg.FormClosed += DialogBClosed;
          _dlg.Show();
        }
        public void DialogBClosed(Object sender, FormClosedEventArgs e) {
          this.Text = "DialogB OK";
          this.Enabled = true;
        }
      }
    
    
      public partial class DialogA : Form {
        private int _ret = 0;
    
        public DialogA() {
          InitializeComponent();
        }
        private void btn_Click(object sender, EventArgs e) {
          if(sender == btnCancel) _ret = 1;
          this.Close();
        }
        public int ReturnCode {
          get { return _ret; }
        }
      }
    
    
      public partial class DialogB : Form {
        private int _ret = 0;
    
        public DialogB() {
          InitializeComponent();
        }
        private void btn_Click(object sender, EventArgs e) {
          this.Close();
        }
        public int ReturnCode {
          get { return _ret; }
        }
      }
    

    (ホームページを再開しました)
    2010年8月10日 5:13
  • 外池さん,いつまでも気にかけて下さって頂いておりますことに感謝申します。

    ただ,ビルドして実行する段階ではこの現象は現れないはずですので,複雑なコードは書かないことにしようかと思っております。


    zen73
    2010年8月11日 0:18