- - PR -
デザイナのないクラス(WindowsFormでない)でのコントロールの扱い
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2008-04-09 15:54
失礼いたします。
VB2005にて開発を行っています。 ******************************************************************************************** 'Windowsフォーム Public Class Main 'マウスダウンイベント------------------------------ Using frmDialog As New DialogP If frmDialog.ShowDialog(Me) = Windows.Forms.DialogResult.Cancel Then Exit Sub End If End Using '--------------------------------------------------- Public Shared Sub PartsItemValidating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) '数値か?など End Sub ******************************************************************************************** 'Windowsフォーム Public Class DialogP 'Load イベント------------------------------ Me.Panel.Controls.Add(Parts.PartsText) -------------------------------------------- Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click Me.DialogResult = Windows.Forms.DialogResult.Cancel Me.Close() End Sub ******************************************************************************************** 'デザイナのないクラス Public Class Parts Public Shared PartsText As New TextBox Public Sub New() 'PartsTextに対してプロパティ指定 PartsText.Text = "あああ" ・・・・ AddHandler PartsLabel.Validating, AddressOf PartsItemValidating ********************************************************************************************* 1回目に frmDialog.ShowDialogする時は問題ないのですが、 2回目以降、宣言部分の Public Shared PartsText As New TextBox をとおらないため DialogPクラスのMe.Panel.Controls.Add(Parts.PartsText)で "破棄されたオブジェクトにアクセスできません。"となります。 またUsingで破棄しないと、AddHandlerのイベントが追加した回数分だけ実行されてしまします。 どうすればいいのか悩んでいます・・・ そもそもPartsクラスでコントロール宣言、プロパティ設定など しているのが間違いなのでしょうか? 何か解決法をご教授願います。 [ メッセージ編集済み 編集者: 108 編集日時 2008-04-09 15:58 ] [ メッセージ編集済み 編集者: 108 編集日時 2008-04-09 16:00 ] | ||||
|
投稿日時: 2008-04-09 16:01
そう思います。 今回の問題は共有メンバになっていることから起因している問題と言えます。 共有メンバのままにしたいなら PartsLabel は Dispose および参照の解放をしてはいけません。 逆にインスタンス メンバであればコンストラクタでインスタンスの生成を強制できます。 と思ったのですが、コンストラクタで共有メンバ PartsLabel に何かしていますね。 これだと共有メンバの意味がない (整合性が取れていない) ような気がします。 何をしたいがためのコードなのでしょうか? 代替案が提示できやもしれません。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||
|
投稿日時: 2008-04-09 16:46
ご返答ありがとうございます。
実際のクラスはPartsを継承したPartsText、PartsWindowなど15種ほどあります。 目下のしたいことは、 Mainから部品ボックスダイアログを表示(Show)し、PartsTextを選択するとします。 そのままMainのパネルにマウスダウンするとさらにDialogPが開きます。 (PropertyGridではない) PartsTextクラスの情報によって マウスダウン時の座標TextBox、フォントカラーComboBox などのコントロールを動的に追加します。 ↓DialogP ----------------------------------------- 項目名 | 値 ]座標(ラベル) | TextBox フォントカラー(ラベル) | ComboBox ▼ ・・・・など OK キャンセル ------------------------------------------ OK押下時に、入力された情報をPartsTextクラスに保持し、 DialogPを閉じて、その情報からMainのパネル上 にTextBoxを追加します。 既に追加されたコントロール上でマウスダウンした場合はどのクラスの部品かを特定して Mainのプロパティ表示域に値をセット →レイアウトはボタンがないだけでほぼ同じ。 このためPartsTextクラス内で先にプロパティをセットしておけば Mainでは追加するだけでいいかなぁと考えてしまいました。 何かいい方法はございますでしょうか・・・ | ||||
|
投稿日時: 2008-04-09 17:21
外しているかもしれませんが、選択した結果を返すようなダイアログがいくつか組み合わさり、さらにダイアログごとに GUI が動的に変わるようなものを想像しました。 であれば、やはりダイアログとして表示される Form 自体で実装すべき機能 (Label や TextBox のことです) だと思います。 分離すべき場所が誤っているように思います。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||
|
投稿日時: 2008-04-09 17:40
じゃんぬねっと様。
ご返答ありがとうございます。 ではParts***クラスでは、単純に値のみ保持するような作りで、 ダイアログFormの方でCase分岐によりそのつど Dim XPosition as New TextBox などとしてADDすることにします。 誤っていると指摘されたことで助かりました。 ありがとうございました。 | ||||
|
投稿日時: 2008-04-09 17:48
Parts*** がダイアログから返却されるようなデータであれば、それで良いと思います。 俗に言う 「データクラス」 というやつですね。 ダイアログによって扱うデータが違うのであればこのクラスを継承して利用することもできます。 ただ GUI (ダイアログ自体) の方が少々厄介ですね。 可変的な拡張でなければ、最初から Control を追加しておいて非表示にしておくとか、入力項目のみユーザーコントロールを利用してコンテナ化するとかしないとコードが無駄に膨れ上がってしまいます。 いくらダイアログであっても GUI に関するコードは極力抑えた方が保守しやすいです。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||
|
投稿日時: 2008-04-09 18:12
補足ですが、今回でいう Parts クラスのような、フォームからフォームに受け渡すクラスに
コントロールのインスタンスを持たせてしまうと、 リソースの破棄(Dispose の呼び出し)の責任の所在があやふやになりやすいです。 また、再利用性の低い設計(そのフォームとの組み合わせでないと使えない)とも言えます。 1つの案として、こんな設計はどうでしょうか?
これでダイアログが Parts のインスタンスを返せば、 MainForm 側で CreateControl を呼び出してコントロールを作成することができます。 この場合 Dispose は当然、MainForm 側で行うことになります。 UIは、じゃんぬねっとさんもおっしゃっていますが、 コードで1つずつ追加するよりは、UserControl などにまとめたほうがいいような気がします。 15個も作るのは面倒かも知れませんが、デザイナで修正できる方が、 あとから配置を少し変えたいといったときに、柔軟に対応できます。 | ||||
|
投稿日時: 2008-04-09 18:31
そうなんです。 えらい膨れ上がってしまいまして・・・ 最初は、とりあえず重複しない最大部品数分追加しておいて表示・非表示を切り替えて、 Locationをずらして表現しようかなと思ったのですが、 それを試す前に、先にやっとけないかと思った結果上記のようにハマリました。 余談ですが、 XML読込みから部品追加、TreeView・DOMとの同期、最背(前)面へ移動、背(前)面へ移動、XML出力、二重起動での切り取り・貼り付け等々未知の機能が満載です・・・ 先が思いやられます。 またお力をお借りするかと思いますが、宜しくお願いします。 |