- PR -

異なる複数のコントロールから同一の動作を行う方法について

投稿者投稿内容
taa
常連さん
会議室デビュー日: 2005/08/29
投稿数: 44
投稿日時: 2005-10-28 15:56
こんにちは。VB.NETの初心者です。

現在、Windowsアプリケーションを開発しており、
コマンドボタンをクリックした時とメニューバーより選択した
アイテムをクリックした時に、共通の動作が行われるように
したいと思っています。
(例えば、Excelのメニューバーとツールバーにある上書き保存の
イベントが同じ動作をするように)

一応、今は、以下(※プログラムコード)のようにコーディング
しており、技術的にできないという質問ではありませんが、
ポリモフィズムなどのオブジェクト指向プログラミングの技術
を勉強している中で、もっとより良いプログラミング方法が
あるではないかと思い、質問しています。

皆さんはどのようにプログラミングを
しているのか教えてください。

<開発環境・言語>
VS2003、VB.NET

<プログラムコード>
それぞれのコントロールのイベント毎に同じ処理を記述しています。

Public Class Form1

※省略

Private Sub MenuItem2_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles MenuItem2.Click

Dim rc As Integer
rc = OutPutMessage

End Sub

Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles Button1.Click

Dim rc As Integer
rc = OutPutMessage

End Sub

Private Sub OutPutMessage() As Integer
MessageBox.Show("なんか上手い方法がないかなぁ")
End Function

End Class
たつごろー
ぬし
会議室デビュー日: 2004/10/25
投稿数: 496
投稿日時: 2005-10-28 16:09
共通の処理をクラスにして、おのおののFormにあるイベントプロシジャから呼び出すとよいと思います。

Visual Basic 言語の概念
チュートリアル : クラスの定義
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vbcn7/html/vbconClassModuleStepByStep.asp


_________________
たつごろー
codeseek
こみゅぷらす
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-28 16:09
"全く同じ動作をさせる" とのことですので、
静的メソッドにその「共通」を実装し、それぞれのイベントで呼び出す。
イベント ハンドラをいちいち実装したくないのであれば、AddHandler で追加するとか。
コントロールの列挙は For Each 何かを使えばできます。

違うタイプのコントロールであれば、普通にイベントに実装しても問題ないですよね。
むしろ、そこまで統合しちゃうと返って見難いソースが出来上がります。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
葉瀬崎浩樹
大ベテラン
会議室デビュー日: 2005/06/28
投稿数: 115
お住まい・勤務地: 兵庫県
投稿日時: 2005-10-28 16:16
VB.NETのコードには不案内なので、考え方だけ。

2つのボタンのクリックイベントに対して、
1つのイベントハンドラを登録します。

図にすると、こんな感じかな。
コード:

[イベント] [イベントハンドラ]
MenuItem2.Click ┐
├→共通処理_Click
Button1.Click  ┘



件名に対する回答としては、
他にもいろいろあるのですが、
とりあえずシンプルな方法かと。

#図がずれたのでタグ追加。

[ メッセージ編集済み 編集者: 葉瀬崎浩樹 編集日時 2005-10-28 16:28 ]
taa
常連さん
会議室デビュー日: 2005/08/29
投稿数: 44
投稿日時: 2005-10-28 16:44
たつごろーさん、じゃんねねっとさん、返答ありがとうございます。
不明な内容もありましたので、以下にコメント致します。

引用:

共通の処理をクラスにして、おのおののFormにあるイベントプロシジャから呼び出すとよいと思います。


そうですね。SubプロシージャよりClassの方が一般的なので、今後の事も考え修正したいと思います。

引用:

"全く同じ動作をさせる" とのことですので、
静的メソッドにその「共通」を実装し、それぞれのイベントで呼び出す。


これは、SubプロシージャからClassのメソッドへ変更する事を
意味しているのでしょうか?

引用:

イベント ハンドラをいちいち実装したくないのであれば、AddHandler で追加するとか。


これは、それぞれのコントロールのクラスを作成し、
動的生成した際にハンドル名が同じのイベントを"AddHandler"して追加
するという事でしょうか?

引用:

コントロールの列挙は For Each 何かを使えばできます。


この文章はなんとなく意味はわかるけれども、実現方法がわかりませんでした。

一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2005-10-28 17:05
私は、taaさんの提示した方法が最も良いと思います。
MenuItem2_Click()はMenuItem2.Clickイベント時の処理を行うという意味を持っています。
(いや、持っているかどうかはtaaさんが決めることですが、多分そうだろうと思います)
そして、Button1_Click()はButton1.Clickイベント時の処理を行うという意味を持っています。
MenuItem2.Click時にある処理(ファイル書込みとか)をしたいのであれば、その処理を行うメソッドを呼びます。
Button1.Click時にある処理をしたいのであれば、その処理を行うメソッドを呼びます。
これで何の問題もないですよ。

MenuItem2のクリック時の処理に変更があった場合に、Button1のクリック時の処理にも影響があるというのはおかしいでしょ。
いや、Button1に表示されているテキストが"メニューの2番目のクリック"とかいうなら話は別ですけどね。
それなら、Button1_Click()内でMenuItem2_Click()を呼べばいいです。


余談ですが、
Private Sub OutPutMessage() As Integer
これ、SubなのにAs Integerですか?

[ メッセージ編集済み 編集者: 一郎 編集日時 2005-10-28 17:18 ]
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-10-28 18:18
引用:

taaさんの書き込み (2005-10-28 16:44) より:

これは、SubプロシージャからClassのメソッドへ変更する事を
意味しているのでしょうか?


いいえ。ビジネスロジック部分のみを静的メソッドに置き換えて、
同じメソッドを複数のイベントから呼び出すということです。
というより、taa さんが最初に提示した方法と同じ原理です。
ただ、静的 (Shared) メソッドにすべきなのでは? と思っただけだったりします。

引用:

これは、それぞれのコントロールのクラスを作成し、
動的生成した際にハンドル名が同じのイベントを"AddHandler"して追加
するという事でしょうか?


クラスを作成する必要はないですよね?
インスタンスは生成しなければなりませんが。

AddHandler を動的に追加するという点は合っています。
ただしこれは「コントロールの配列」の概念があるコントロールに限ります。
それ以外の組み合わせ、たとえば、Menu と Button を合わせるのは可読性を損ないます。

引用:

この文章はなんとなく意味はわかるけれども、実現方法がわかりませんでした。


For Each を使って、Form 内のすべてのコントロールを列挙し、
TypeOf [object] Is [type] でコントロールを識別して、動的にハンドラへ追加するという話です。
あまり宜しい実装とは言えません。

コントロールの配列であっても手動で追加していくのが一般的です。
今回のような例では使えませんね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ジブ
大ベテラン
会議室デビュー日: 2005/09/22
投稿数: 135
投稿日時: 2005-10-28 18:49
メニューとコマンドボタンなら単純に

コード:
    Private Sub OutPutMessage(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, MenuItem2.Click
        MessageBox.Show("共通")
    End Sub


でOkかと

スキルアップ/キャリアアップ(JOB@IT)