- ベストアンサー
VB.netでフォームのクローン
VB.net2013にて、フォームアプリ作成中です。 アプリの構成としては、 Aフォーム、Bフォームの2画面があり Aフォームの呼出ボタンにより、フォームを呼び出す仕組みです。 Bフォームでは、データ編集できる 下記のような入力コントロールが多数配置されています。 ・テキストボックス ・スプレッドシート ・ラジオボタン ・ユーザコントロール各種 等々 ※Aフォームには、編集状態を保持するために Bフォームのインスタンスを保持しています。 Bフォームには、キャンセルボタンが配置してあり、 これにより編集状態を、画面を開きなおした段階まで戻したいと思っています。 Bフォームを表示する際に、 Aフォームの保持している、Bフォームのインスタンスを クローンコピーし退避しておくことで Bフォームクローンで元に戻そうと構想しています。 ◾︎案1ーーー memberwisecloneのクローンでは、 Bフォームの参照型のメンバをディープコピー出来ないようでした。 ーーーーーー ◾︎案2 ーーー 下記参考サイトより、 メモリ上に一旦シリアライズして、コピーする方法は、 基底であるFormクラスがシリアライズできないため こちらも出来ませんでした。 d.hatena.ne.jp/tekk/touch/20100131/1264913887 ーーーーーー フォーム上のコントロールをクローンする 他に良い方法はないでしょうか? 案1では、値型のメンバはmemberwisecloneでクローン出来たため 残りのコントロールをどのようにディープコピーするかで 悩んでいます。 InvokeMemberなるもので、対象のコントロールについて 別インスタンスを生成するというところは出来たのですが コントロールの編集途中までの各種プロパティ値までは 引き継がれませんでした。 やはり別インスタンスとしたところに 再度入力値を設定しなおしてあげる必要があるのでしょうか? 作業工数と、汎用性を考えると もっと他に良い方法があるのではないか とは思うのですが・・・ もしよりよい方法をご存知の方いらっしゃいましたら ご教授願います。よろしくお願いいたします。
- みんなの回答 (2)
- 専門家の回答
みんなが選んだベストアンサー
> フォーム上のコントロールをクローンする > 他に良い方法はないでしょうか? クローンしない。 その代りに以下のようにする。 ・Bフォームで編集するデータを表すクラス(以下、「データクラス」と略記)を用意する。 ・Bフォームにデータクラスのインスタンスをもとにフォームの状態を変更するメソッド(以下、「状態変更メソッド」)を作る。 ・また、Bフォームに現在のフォームの状態からデータクラスのインスタンスを新規生成して返すメソッドを作る。 ・そのうえで、AフォームからBフォームを表示する際に、 (1) データクラスのインスタンスを生成する。 (2) Bフォームインスタンスを生成する。この時上記で生成したデータクラスインスタンスをBフォームに渡しておく。 (3) Bフォームでは渡されたデータクラスインスタンスを初期値として保持したうえで、状態変更メソッド呼び出す。 (4) 上記が終わったなら、AフォームでBフォームを表示させる。 ということを行う。 ・Bフォームでは初期値として保持しているデータクラスインスタンスは絶対変更しない。 ・Bフォームでキャンセルボタンが押された時、状態変更メソッドを呼び出す。これで表示状態は初期状態に戻る。 ・Bフォームが閉じたとき、AフォームではBフォームのデータクラスインスタンス生成メソッドを呼び出し、その戻り値をもとにもとのデータを修正する。 ……ところで、キャンセルボタンと書くと、どうしても「何もせずにフォームを閉じる」というイメージがあります。 問題のボタンは「初期値に戻す」ボタン、あるいは「リセット」ボタンと呼んだほうがよろしいかと思います。
その他の回答 (1)
- wormhole
- ベストアンサー率28% (1626/5665)
MVCでいえばViewにあたるFormにModelの役割もさせようとしてるのが、そもそもの間違いかと。 データはModelに持たせておいてFormの初期表示時にはModelを参照して表示、キャンセル時も同様。
お礼
感謝します。この方法を参考に実装完了できました。 ありがとうございます!
お礼
返信が遅くなりましたが、ありがとうございます。 これは私の書き方が悪かったので申し訳ないですが、 実装したいものは「何もせずにフォームを閉じる」でしたので リセットボタンではなく、キャンセルボタンということになります。 大変丁寧な回答感謝の限りで、申し訳ないのですが 他の方がこの質問回答を参考にされる方もいることを考えると 誤解を招いてしまうかもしれないため、ベストアンサーとできませんでした。 代わりにありがとうボタンとさせていただきたく思います。 感謝です。ありがとうございました!