- PR -

ユーザーコントロールの引数ありコンストラクタを作って呼ぶ方法

投稿者投稿内容
siop
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 67
投稿日時: 2004-11-09 18:39
引数ありのコンストラクタを作っても、Formからそのコンストラクタを
呼ぶことができず困ってます。

以下に手順を書きます。

(1).テキストボックスとボタンを貼り付けたユーザーコントロールを作ります。
(2).インスタンス生成と同時にTextBox1.Textへ値を表示したいため、
  引数ありのコンストラクタを作成します。

Public Sub New(ByVal aText As String)
  MyBase.New()

  ' この呼び出しは Windows フォーム デザイナで必要です。
  InitializeComponent()

  ' InitializeComponent() 呼び出しの後に初期化を追加します。
  Me.TextBox1.Text = aText
End Sub

(3).Formにユーザーコントロール貼り付けます。
(4).引数ありのコンストラクタを呼ぶようにコードを修正します。

Me.UserControl11 = New WindowsApplication4.UserControl1
↓このように修正
Me.UserControl11 = New WindowsApplication4.UserControl1("ABC")

(5).実行すると、思ったとおりの動きをしています。

しかし、

(6).Formで何らかのデザインを修正します。(コントロールを動かすなど)
(7).再度、ソースを開くと、修正前の状態に戻ってしまいます。

↓こうなっている。自動で変換されたようだ。
Me.UserControl11 = New WindowsApplication4.UserControl1

こんなもんなのでしょうか?

何か回避策はありませんでしょうか?
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2004-11-09 18:48
そんなもんじゃないかと・・・。

対策としては、
1.コンストラクタの引数でパラメタを渡すのをやめる。
2.フォームデザイナを使わずに、自前のコードでコントロールを表示する。

ユーザーコントロールとして作ったのですから、他のユーザーコントロールの流儀に合わせて、コンストラクタでパラメータを渡すのではなくプロパティで設定できるようにした方が良いと思う。
siop
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 67
投稿日時: 2004-11-09 19:03
引用:

対策としては、
1.コンストラクタの引数でパラメタを渡すのをやめる。
2.フォームデザイナを使わずに、自前のコードでコントロールを表示する。


"2"に関しては、実現できました。
デザイナで見ることはできないのが難点ですが、しょうがないですかね。

"1"に関しては、"2"が実現できた以上、必要ないのではないでしょうか?
サンプルでは簡単な例でしたが、実際にコンストラクタ内でやりたいことは
データベースにアクセスし、データを表示することです。
処理を隠蔽したいので、Formからコンストラクタを呼び出すだけにしたいんです。

「他のユーザーコントロールの流儀」って言うのが気になるのですが、
そういう流儀があるのですね。どうしようかな。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2004-11-09 23:35
引用:

処理を隠蔽したいので、Formからコンストラクタを呼び出すだけにしたいんです。



GUI コンポーネントに関して言えば、コンストラクタで込み入った処理を行うのは避けるのが無難です。

例えば、デザインモードでDB接続に行ったら困る場合なんかもありますよね?

_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
siop
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 67
投稿日時: 2004-11-10 04:19
引用:

GUI コンポーネントに関して言えば、コンストラクタで込み入った処理を行うのは避けるのが無難です。

例えば、デザインモードでDB接続に行ったら困る場合なんかもありますよね?


なるほど。これが流儀なんですね。
ただ、実際にコンストラクタで行ってることは、引数をプロパティ(メンバー変数)へ代入してるだけです。
ユーザーコントロールのLoadイベントでメンバー変数をキーにしてDB取得を行っています。

なので、デザインモードでDB接続は行われていないと思います。

ユーザーコントロールを貼り付けたFormのLoadイベントでプロパティへ代入することも
考えたのですが、ユーザーコントロールのLoadイベントが早く実行されるので、
やむなくコンストラクタで渡すことにしたのです。

つまり、
GUIコンポーネントのコンストラクタに引数を持たすなら、デザインモードは使えない。

ってことで、何らかの手を打つ必要がありますね。
デザインモードが使えないと、後からのメンテナンスで弊害がでそうなので、別の手を考えます。
siop
ベテラン
会議室デビュー日: 2003/08/12
投稿数: 67
投稿日時: 2004-11-10 04:41
こんな方法でいくことにしました。

(1).ユーザーコントロールのコンストラクタはそのまま。
(2).ユーザーコントロールのLoadイベントでも何もしない。
(3).ユーザーコントロールでDB接続してデータを取得しセットするPublicメソッドを作成。
(4).FormのLoadイベントで、(3)のメソッドを呼ぶ。

下記のソースはDB接続はやってませんが、サンプルということで・・・。

<ユーザーコントロール>
Public Class UserControl1
  Public Sub setTxt(ByVal atxt As String)
    Me.TextBox1.Text = atxt
  End Sub
End Class

<Form>
Public Class Form1
  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    UserControl11.setTxt("ABC")
  End Sub
End Class
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-11-10 19:28
 パラメータじゃなく、プロパティ(ウインドウ)で渡すようにすればいいのでは?
#属性を調べてください

_________________
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2004-11-10 23:50
>ユーザーコントロールのLoadイベントでメンバー変数をキーにしてDB取得を行ってい>ます。
(略)
>ユーザーコントロールを貼り付けたFormのLoadイベントでプロパティへ代入することも
>考えたのですが、ユーザーコントロールのLoadイベントが早く実行されるので、
>やむなくコンストラクタで渡すことにしたのです。

てことなら、ISupportInitialize を実装してみるのもひとつの手でしょう。
ISupportInitialize を実装すれば、IDE はそれを気に留めてくれます。

ただ、それよりもフォームの Load でコントロールのメソッドを呼び出して、そこで DB 接続をする方が(私には)素直な設計に思えます。

_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/

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