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

複数フォームの移動

環境/言語:[OS : Windows XP Home Edition / 言語 : Visual Basic .NET]
分類:[.NET]

【解決したい問題】

また投稿させて頂きます。

一つのメインフォーム(Main)から、複数のサブフォーム(例えば、Sub1、Sub2、Sub3・・・etc)にアクセスしようとしています。
サブフォームは、常に、モーダルフォームとして表示したいです。

Mainからサブフォームへは、showdialogを利用して、表示できました。

今度は、例えば、Sub1のフォーム上に、「次へ」というようなボタンを作成し、
これをクリックすることで、Sub1のフォームを閉じて、
Mainを介さずに、Sub2へ直接、移動したいと考えています。
これを「次へ」ボタンのイベントプロシージャーClickで記述しようと試みたのですが、結局、以下のようにモードレスフォームとしては移動できたのですが、モーダルフォームとして表示する方法がわかりません。

me.dialogResult=dialogResult.OK
Sub2.Show

どなたかおわかりになる人がいましたら、教えてください。

よろしくお願いいたします。
こんにちは、じゃんぬ です。

■No12891に返信(BBさんの記事)
> 結局、以下のようにモードレスフォームとしては移動できたのですが、
> モーダルフォームとして表示する方法がわかりません。

モーダルの場合、呼び出し元に制御を移さないで遷移させることはできません。
呼び出し元に制御を移してください。

こういう場合はフォームに合わせて UserControl を貼り付けるなどして、
同じフォームで、見えている場所を変えるなどしてます。
インストーラの [次へ] みたいなものは、こうやって作ってますね。
じゃんぬさん:

BBです。

■No12894に返信(じゃんぬねっとさんの記事)
> モーダルの場合、呼び出し元に制御を移さないで遷移させることはできません。
> 呼び出し元に制御を移してください。

わかりました。

> こういう場合はフォームに合わせて UserControl を貼り付けるなどして、
> 同じフォームで、見えている場所を変えるなどしてます。
> インストーラの [次へ] みたいなものは、こうやって作ってますね。

私の解釈が間違っているかもしれませんが、
これは、複数のフォームの大きさなどを統一させるということでしょうか?
また、呼び出し元から制御するというのは、
呼び出し元のFormのパブリックイベント内で記述するということですよね?
その場合、どのイベントを利用するのが適切なのですか?

見当違いな発言ならすみません。

よろしくお願いします。
こんにちは、じゃんぬ です。

■No12905に返信(BBさんの記事)
> 私の解釈が間違っているかもしれませんが、
> これは、複数のフォームの大きさなどを統一させるということでしょうか?

別にフォームの大きさは、その都度動的に変えられますよね。
[次へ] ボタンを押下した時点とか。

> また、呼び出し元から制御するというのは、
> 呼び出し元のFormのパブリックイベント内で記述するということですよね?

呼び出し元の Form の Public イベント?
呼び出し元は別に何でも良いのではないでしょうか?
呼び出し元がどこからか制御されるわけじゃないですし。(いや、されちゃまずい)
Public で公開する意味もないですし、イベントでなくてもいいですし。

> その場合、どのイベントを利用するのが適切なのですか?

仕様に依ると思います。
どのタイミングで表示させたいのかは、流石に判らないです。
■No12906に返信(じゃんぬねっとさんの記事)
私の説明が上手く伝わらなかったようで申し訳ありません。

その後、いろいろ試しているのですが、やはり上手くいきません。

試行錯誤の一例を示しますと、
たとえば、Main.vb、Sub1.vb、Sub2.vbがあるとします。

Main.vbからSub1.vbをモーダルフォームとして開きます。
そして、Sub1.vbから「次へ」のボタンをクリックして、
Sub2.vbを開きたいとします。

そこで、Sub1.vbの「次へ」ボタンのクリックイベントとして、

Private Sub btnNext_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnNext.Click
Me.DialogResult = DialogResult.OK
myNextForm = "Sub2PopUp"
End Sub

と記述します。

そして、Main.vbには、

Private Sub Main_Activated(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Activated
Select Case myNextForm
Case "Sub1PopUp"
Sub1.ShowDialog()
Case "Sub2PopUp"
Sub2.ShowDialog()
End Select
myNextForm = "NonePopUp"
End Sub

こうすることで、Sub1の「次へ」ボタンをクリックすることで、
Sub1が閉じて、Sub2がモーダルフォームとして開くはずだと考えました。
しかし、実際にはSub1が閉じられず、Sub2と二重に開くことになり、
エラーメッセージが生じてしまいます。

こういった場合には、どうすれば宜しいでしょうか?
こんにちは、じゃんぬ です。

■No12966に返信(BBさんの記事)
> 私の説明が上手く伝わらなかったようで申し訳ありません。

いや、伝わってないのは私の方かもしれませんね。
UserControl の話は却下されましたか...

UserControl の表示を切り替えることで、Form は単一で済みます。
Form の遷移などを考える必要がない、保守性も良いと思ったのですが...

> こうすることで、Sub1の「次へ」ボタンをクリックすることで、
> Sub1が閉じて、Sub2がモーダルフォームとして開くはずだと考えました。
> しかし、実際にはSub1が閉じられず、Sub2と二重に開くことになり、
> エラーメッセージが生じてしまいます。
> こういった場合には、どうすれば宜しいでしょうか?

回避策を考える前に原因をつかみましょう。
ブレークポイントを設定して追ってみてください。
フォーカスが絡むので、適宜 F5 実行などする必要はありますが、
原因はいとも簡単に掴めると思いますよ。
じゃんぬさん:

BBです。

> 回避策を考える前に原因をつかみましょう。
> ブレークポイントを設定して追ってみてください。
> フォーカスが絡むので、適宜 F5 実行などする必要はありますが、
> 原因はいとも簡単に掴めると思いますよ。

原因は、はっきりとはわからなかったのですが、
とにかく、このままでは、ダイアログボックスが閉じる前に、
呼び出し元のフォームがアクティブになってしまうのが、
原因なのですよね。

そこで、似たようなコードを標準モジュールで作成し、
スタートアップをSub Mainとして、
全てのダイアログボックスを、
標準モジュールから呼び出すことで、
とりあえず、解決しました。

> いや、伝わってないのは私の方かもしれませんね。
> UserControl の話は却下されましたか...
>
> UserControl の表示を切り替えることで、Form は単一で済みます。
> Form の遷移などを考える必要がない、保守性も良いと思ったのですが...

いえいえ、決して却下したわけではございません。
私自身が、UserControlを利用したことがなかったので、
UserControlについては、ただいま、勉強中でして、
やっと、以前、じゃんぬさんが仰っていた、

> 同じフォームで、見えている場所を変えるなどしてます。

という意味がわかり始めたところです。

いつも迅速な返信、ありがとうございました。
解決済み!
  • 題名: Re[7]: 複数フォームの移動
  • 著者: なおこ(・∀・)
  • 日時: 2005/09/28 16:19:23
  • ID: 13005
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
お世話になります。

完全に蛇足だと思うのですが…。
私もやってみました。

=========================
Form1のコード
=========================
Public m_Nextformname As String

Public Property Nextformname() As String
  Get
    Return Me.m_Nextformname
  End Get
  Set(ByVal Value As String)
    Me.m_Nextformname = Value
  End Set
End Property

Private Sub Form1_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated

  Select Case Me.m_Nextformname
    Case "Form2"
      Dim f2 As Form2 = New Form2
      f2.ShowDialog(Me)
      f2.Dispose()
    Case "Form3"
      Dim f3 As Form3 = New Form3
      f3.ShowDialog(Me)
      f3.Dispose()
  End Select
  Me.m_Nextformname = ""

End Sub

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Me.m_Nextformname = "Form2"
End Sub

=========================
Form2のコード
=========================
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  CType(Me.Owner, Form1).Nextformname = "Form3"
  Me.Close()
End Sub

=========================
Form3のコード
=========================
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  CType(Me.Owner, Form1).Nextformname = ""
  Me.Close()
End Sub
解決済み!

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