C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: Newで作成したフォームのボタンを押したい


(過去ログ 114 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■67667 / inTopicNo.1)  Newで作成したフォームのボタンを押したい
  
□投稿者/ 寅 (15回)-(2013/08/22(Thu) 22:02:52)

分類:[.NET 全般] 

今、VB.net 2010 Expressでプログラムを作成して居ます。

フォーム1からフォーム2にあるButton1をクリックさせるには
Form2.Button1.PerformClick()
とやりますよね。

これと同じ事をNewで表示させたボタンでさせる事は出来るでしょうか。
プログラムするFormは通常のフォームからとします。

Public DxCam0 As Form 'データー領域を確保します。

DxCam0 = New DirectShowIF  'DirectShowIFのフォームを作ります。
DxCam0.Show()        'DirectShowIFのフォームを表示します。

このDirectShowIFにあるボタンButton2を他のフォームからクリックしたいのですが、出来ますでしょうか。

因みに以下のコーディングは全てNGでした。

DirectShowIF.Button2.PerformClick() 'コンパイルエラーでは無いが、実行時にエラーと成る 
                   当然どのnewで作成したか指定して居ないので論理的にもおかしい。
DxCam0.Button2.PerformClick()     'コンパイルエラー

宜しくお願い致します。
引用返信 編集キー/
■67670 / inTopicNo.2)  Re[1]: Newで作成したフォームのボタンを押したい
□投稿者/ 魔界の仮面弁士 (310回)-(2013/08/23(Fri) 01:37:45)
No67667 (寅 さん) に返信
> フォーム1からフォーム2にあるButton1をクリックさせるには
> Form2.Button1.PerformClick()
> とやりますよね。
VB であればそう書けますね(コントロールの Modifiers が Friend レベルなので)。

これが C# だと、コントロールは既定で private レベルになるので、
設定を変更しない限りは、そういった書き方は出来ないのですが。

ただいずれにせよ、フォームの外部から、コントロールを直接操作するような
設計は、あまり望ましくありません。フォームのレイアウトを変更すると、
それを呼び出している箇所すべてを直さなければいけなくなってしまうため、
こういう時は、コントロールを操作するためのプロパティなりメソッドなりを
公開してやり、コントロールそのものは隠蔽して置いた方が良いでしょう。


> これと同じ事をNewで表示させたボタンでさせる事は出来るでしょうか。
> プログラムするFormは通常のフォームからとします。
DxCam0 を DirectShowIF に DirectCast して呼び出すとか。
引用返信 編集キー/
■67672 / inTopicNo.3)  Re[2]: Newで作成したフォームのボタンを押したい
□投稿者/ 寅 (16回)-(2013/08/23(Fri) 07:39:56)
No67670 (魔界の仮面弁士 さん) に返信
> ■No67667 (寅 さん) に返信

ご回答有難うございます。
ただ、私は現在、VBの機能を理解しようとしており、機能自体を知りたいのです。
何故通常のフォームにはアクセス出来て、Newで作ったフォームにはアクセス出来ないのかが主題です。

引用返信 編集キー/
■67675 / inTopicNo.4)  Re[3]: Newで作成したフォームのボタンを押したい
□投稿者/ 魔界の仮面弁士 (311回)-(2013/08/23(Fri) 09:10:39)
No67672 (寅 さん) に返信
> ただ、私は現在、VBの機能を理解しようとしており、機能自体を知りたいのです。
機能…? ですから、DirectCast 等で「キャスト」すれば良いのですよ。

> 何故通常のフォームにはアクセス出来て、Newで作ったフォームにはアクセス出来ないのかが主題です。
アクセス出来ますよ、先の回答の最後の行に書いたように。


DxCam0 や DirectShowIF だと分かりにくいので、少し置き換えて話をしますが:

Form1 も Form2 も、Form 型です(Form を継承して、Form1 や Form2 を作っています)。
Form1 には Button1 がありますが、Form2 には Button1 がありません。

全ての Form に Button1 があるわけでは無いため、Dim f As Form に対して、
f.Button1 のようにアクセスすることはできません。

ですが、変数 f の中身が Form1 であるならば、その Form が Form1 であることを
VB に伝えてやれば、Button1 にアクセスすることできます。それが先の DirectCast であり、
具体的には DirectCast(f, Form1).Button1 のようにして処理できます。

この他にも、レイトバインドを使う方法や、リフレクションを用いてアクセスする方法もありますが、
今回は型が分かっているので、(DirectCast や TryCast で)キャストして呼び出すのが良いでしょう。


とはいえ、Form1 にも Form3 にも Button1 があって、それを共通の仕組みとして呼び出したいなら、
 If TypeOf f Is Form1 Then
  DirectCast(f, Form1).Button1.PerformClick()
 ElseIf TypeOf f Is Form3 Then
  DirectCast(f, Form3).Button1.PerformClick()
 ElseIf …
  …
 End If
のように、インスタンスの種類だけキャストが発生してしまい、共通の Form 型として
管理することができず、汎用化できません。


このような場合には、
 Public Interface ICommonForm
  ReadOnly Property OKButton As Button '☆ Button 型のプロパティを用意する。
 End Interface
といった Interface を用意しておき、各フォーム(Form1, Form3, …)でそれを
Implements するという手が使えます。


 Public Class Form1
  Inherits Form

  Implements ICommonForm '★

  Public ReadOnly Property OKButton As Button Implements ICommonForm.OKButton '★
   Get
    Return Me.Button1
   End Get
  End Property
 End Class


そうすれば呼び出し側では、Form の実際の型にあわせて

 If TypeOf f Is Form1 Then
  DirectCast(f, Form1).Button1.PerformClick()
 ElseIf TypeOf f Is Form3 Then
  DirectCast(f, Form3).Button1.PerformClick()
 ElseIf …
  …
 End If

のように呼び分けずとも、共通して

 If TypeOf f Is ICommonForm Then
  DirectCast(f, ICommonForm).OKButton.PerformClick()
 End If

のように統一化することができます。


もっとも上記の例であれば、Button 等のコントロールそのものを公開するのではなく、

 Public Interface ICommonForm
  Sub OKClick()
 End Interface

のように、ボタンのクリック機能のみを公開したほうが良いかもしれません。
引用返信 編集キー/
■67684 / inTopicNo.5)  Re[4]: Newで作成したフォームのボタンを押したい
□投稿者/ 寅 (18回)-(2013/08/23(Fri) 12:05:33)
No67675 (魔界の仮面弁士 さん) に返信
> ■No67672 (寅 さん) に返信
>>ただ、私は現在、VBの機能を理解しようとしており、機能自体を知りたいのです。
> 機能…? ですから、DirectCast 等で「キャスト」すれば良いのですよ。

すみません、内容を良く理解出来て居なくて。
今、DirectCastで実行した結果、希望の動作が出来ました。

今までEmbacaderoのC++Builderを使用しており、プログラマー責任でアクセスある程度のアクセスは許されて、で、当然間違うと実行時にSTOPしてしまいますが、VB.netは全て機能に許された記述をしないとコンパイル出来ないので四苦八苦しております。

プログラムの最終系では安全面を考慮しますが、現在、動作の検討中の為、手軽に他のフォームにアクセス出来る方法が必要でした。

有難うございました。
解決済み
引用返信 編集キー/
■67692 / inTopicNo.6)  Re[5]: Newで作成したフォームのボタンを押したい
□投稿者/ Jitta (66回)-(2013/08/23(Fri) 22:34:53)
Jitta さんの Web サイト
No67684 (寅 さん) に返信

> 今までEmbacaderoのC++Builderを使用しており、プログラマー責任でアクセスある程度のアクセスは許されて、で、当然間違うと実行時にSTOPしてしまいますが、VB.netは全て機能に許された記述をしないとコンパイル出来ないので四苦八苦しております。
>
> プログラムの最終系では安全面を考慮しますが、現在、動作の検討中の為、手軽に他のフォームにアクセス出来る方法が必要でした。

なんだか、非常な勘違いをされているように思います。

もし、本当に、Visual Studio の機能で、1つのプロジェクトに2つのフォームを追加し(ただし、1つはプロジェクト作成時に自動で追加される)、
Form1 と Form2 というクラス名のクラスを作り、
Form1 のクラス内容を記述したファイルで、
「Form2.Button1.PerformClick()」としたのであれば、
あなたが C++ Builder を使用していた、ということを疑いたいです。
VB も C++ も、「オブジェクト志向言語」です。
オブジェクト志向言語であれば、「Form2」はクラス名として宣言しただけで、インスタンスを作成していません。
よって、アクセスできないはずです。
ただし、VB は、たしか VB 2002〜2003 以外は、フォームを宣言するとクラス名と同じ名前の変数が自動的に作成され、インスタンスが作られます。
これを「暗黙のインスタンス」と言いますが、この「暗黙のインスタンス」が「VB の機能」です。
New 云々は、C++ を使用されていたなら、そちらの方が普通なはずです。

「安全」というのを、どういう意味で使用されているのでしょうか。
今回の問題では、「安全」という言葉が出てくる余地はないはずです。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -