コンボボックスのテキストからフォームを表示
投稿者 るきお  (社会人)
投稿日時
2008/9/27 07:05:09
こんにちは。
あまり一般的ではない要件だと思います。要件を再考することをおすすめしますが、技術的には以下のようにして可能です。
ただし、制限がいくつかあります。呼び出しもとのフォームをForm1とすると、Form1と対象のフォームが同じ名前空間で同じプロジェクト上にある必要があります。
(もっとも上述のプログラムを多少変えればこの制限もとりはらえます)
>「showはstringのメンバではありません」と
VBからみればComboBox1.TextはあくまでもString型なのでこのようになります。
>VBAならこれで動くと思うのですが・・・・
そうでしたっけ?VBAでもVB6でもこの手法では無理なように記憶しています。他の手法でもかなり厳しいです。VB6では不可能といってもいいくらいです。
>根本的に違うのでしょうか?
VBAとVB2008は根本的に違う面もありますが、今回の質問の範囲内では根本的な違いはありません。
あまり一般的ではない要件だと思います。要件を再考することをおすすめしますが、技術的には以下のようにして可能です。
Dim hyouji As String
hyouji = Me.GetType.Namespace & "." & ComboBox1.Text
Dim f As Form
f = Activator.CreateInstanceFrom(Me.GetType.Assembly.Location, hyouji).Unwrap()
f.Show()
ただし、制限がいくつかあります。呼び出しもとのフォームをForm1とすると、Form1と対象のフォームが同じ名前空間で同じプロジェクト上にある必要があります。
(もっとも上述のプログラムを多少変えればこの制限もとりはらえます)
>「showはstringのメンバではありません」と
VBからみればComboBox1.TextはあくまでもString型なのでこのようになります。
>VBAならこれで動くと思うのですが・・・・
そうでしたっけ?VBAでもVB6でもこの手法では無理なように記憶しています。他の手法でもかなり厳しいです。VB6では不可能といってもいいくらいです。
>根本的に違うのでしょうか?
VBAとVB2008は根本的に違う面もありますが、今回の質問の範囲内では根本的な違いはありません。
投稿者 おち  ()
投稿日時
2008/9/27 07:05:47
ありがとうございます。
VBAで試したところ、出来ませんでした。勘違いでした。
余り一般的ではないようなので、分相応にもっと簡単な方法は無いでしょうか?
単純にフォームの数だけボタンかラベルを配置する事くらいなら組めるのですが、「目次」自体は出来るだけコンパクトにしたいのと、今後も数が増える予定なので出来ればコンボボックスかリストでいくのがコンパクトにいけるのではないかと考えています。
たとえば、フォームに番号を割り振って、リストでその番号を選んで表示するなど・・・
VBAで試したところ、出来ませんでした。勘違いでした。
余り一般的ではないようなので、分相応にもっと簡単な方法は無いでしょうか?
単純にフォームの数だけボタンかラベルを配置する事くらいなら組めるのですが、「目次」自体は出来るだけコンパクトにしたいのと、今後も数が増える予定なので出来ればコンボボックスかリストでいくのがコンパクトにいけるのではないかと考えています。
たとえば、フォームに番号を割り振って、リストでその番号を選んで表示するなど・・・
投稿者 あにす  ()
投稿日時
2008/9/27 07:06:16
求められている仕様がいまいちよくわからないのですが、こんなのはどうでしょうか?
これなら簡単だし、フォームを増やすのも楽だと思います。
フォームが増えた場合は
Me.ComboBox1.Items.Add(New Form3())
と追加していくだけです。
このままだと閉じたフォームを再度開こうとしたときにエラーが出るので少し工夫が要りますけどね。
これなら簡単だし、フォームを増やすのも楽だと思います。
Option Strict Off
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.ComboBox1.DisplayMember = "Text"
Me.ComboBox1.Items.Add(New Form2())
End Sub
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim selectedForm As Form = Me.ComboBox1.SelectedItem
selectedForm.Show()
End Sub
End Class
Public Class Form2
Inherits Form
Public Sub New()
Me.Text = "Form2"
End Sub
Private Sub Form2_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
e.Cancel = True
Me.Hide()
End Sub
End Class
フォームが増えた場合は
Me.ComboBox1.Items.Add(New Form3())
と追加していくだけです。
このままだと閉じたフォームを再度開こうとしたときにエラーが出るので少し工夫が要りますけどね。
投稿者 あにす  ()
投稿日時
2008/9/27 07:06:49
>このままだと閉じたフォームを再度開こうとしたときにエラーが出るので少し工夫が要りますけどね。
挙げたコードは上記の問題については修正済みのコードでした。
挙げたコードは上記の問題については修正済みのコードでした。
投稿者 魔界の仮面弁士  ()
投稿日時
2008/9/27 07:07:11
>>1
> VBAでもVB6でもこの手法では無理なように記憶しています。
ちょっと違いますが、このような書き方はできますね。
《VBA》
UserForms.Add("UserForm2").Show
《VB6》
Forms.Add("Form2").Show
《VB2008》
CallByName(My.Forms, "Form2", CallType.Get).Show()
> VBAでもVB6でもこの手法では無理なように記憶しています。
ちょっと違いますが、このような書き方はできますね。
《VBA》
UserForms.Add("UserForm2").Show
《VB6》
Forms.Add("Form2").Show
《VB2008》
CallByName(My.Forms, "Form2", CallType.Get).Show()
投稿者 るきお  (社会人)
投稿日時
2008/9/27 07:07:42
魔界の仮面弁士さん、すばらしいです。
勉強になりました。Myの他の機能にも応用できそうです。
それにC#だと無理というところが、VB中学校の管理者としてちょっとうれしいポイントです。
あにすさんの手法も面白いと思いましたが、ComboBoxに項目を追加するために項目ごとにフォームのインスタンスを作らないといけない点が難点ですかね。
勉強になりました。Myの他の機能にも応用できそうです。
それにC#だと無理というところが、VB中学校の管理者としてちょっとうれしいポイントです。
あにすさんの手法も面白いと思いましたが、ComboBoxに項目を追加するために項目ごとにフォームのインスタンスを作らないといけない点が難点ですかね。
投稿者 おち  ()
投稿日時
2008/9/27 07:08:24
あにすさん 魔界の仮面弁士 ありがとうございます。
あにすさんのコードでイメージ通りのものが出来ました。
前半は理解できるのですが、後半が良く分かりませんでした。
二度目に表示させる為に、格納された名前を一度クリアしているのだと解釈したのですが・・・
少し自分で理解してみます。ありがとうございました。
あにすさんのコードでイメージ通りのものが出来ました。
前半は理解できるのですが、後半が良く分かりませんでした。
Public Class Form2
Inherits Form
Public Sub New()
Me.Text = "Form2"
End Sub
Private Sub Form2_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
e.Cancel = True
Me.Hide()
End Sub
End Class
二度目に表示させる為に、格納された名前を一度クリアしているのだと解釈したのですが・・・
少し自分で理解してみます。ありがとうございました。
投稿者 あにす  ()
投稿日時
2008/9/27 07:08:53
>>7
コンボボックスに入れているのはForm2のインスタンスそのものなので、×ボタン等でフォームを閉じてしまうと、
再度Button1を押してフォームを開こうとしても、インスタンスが無くなっているのでエラーが出るんです。
そこで、フォームが閉じられようとしたとき(Form2_FormClosingメソッド)に、閉じる動作をキャンセル(e.Cancel = True)して非表示(Me.Hide())にしています。再度開こうとしたときには、非表示にしたForm2がそのまま表示されます。
コンボボックスに入れているのはForm2のインスタンスそのものなので、×ボタン等でフォームを閉じてしまうと、
再度Button1を押してフォームを開こうとしても、インスタンスが無くなっているのでエラーが出るんです。
そこで、フォームが閉じられようとしたとき(Form2_FormClosingメソッド)に、閉じる動作をキャンセル(e.Cancel = True)して非表示(Me.Hide())にしています。再度開こうとしたときには、非表示にしたForm2がそのまま表示されます。
投稿者 あにす  ()
投稿日時
2008/9/27 07:09:13
いっそのことプラグインにしちゃうってのも面白いと思います。
http://dobon.net/vb/dotnet/programing/plugin.html
サンプルをC#で>1の仕様に合わせて修正してみたら上手くいったので、VBでも問題ないと思います。
http://dobon.net/vb/dotnet/programing/plugin.html
サンプルをC#で>1の仕様に合わせて修正してみたら上手くいったので、VBでも問題ないと思います。
VBAでプログラムに興味をもって、最近VB2008を始めました。
目次と、その他のフォームからなるプログラムを作ろうとしています。
combobox1にフォーム名が表示させ、button2をクリックすると
そのnameを持ったフォームが表示されるようにしたいのですが、それ以前に
「showはstringのメンバではありません」と
エラーになります。VBAならこれで動くと思うのですが・・・・
根本的に違うのでしょうか?