DOBON.NET DOBON.NETプログラミング掲示板過去ログ

C#で別プロジェクトのフォームを動かしたい

環境/言語:[環境 Windows 2000,言語 C# NET Framework SDK (ver1.1)]
分類:[.NET]

2004/02/16(Mon) 18:51:20 編集(投稿者)

はじめまして。
最近はじめてC#を触ったものです。
同一ソリューション内に別プロジェクトをいくつか作り、メインメニュー画面から
ボタンクリックなどのイベントを起こして、他のプロジェクトのフォームを動かそうと
していますが、うまくできません。
どのようにソースを作りこみ、どのように指定すればいいのか教えてください。

新規でプロジェクトやソリューションを作るとき、すべてWindows アプリケーション
で行いました。

・開発環境:Microsoft Visual Studio .NET 2003
・言語:C#
デザイナからは他のプロジェクトのフォームを動かす場合、メインとなるプロジェクト(Mainメソッドを持つプロジェクト)以外のプロジェクトはDLL(クラスライブラリ)である必要があります。DLLの中にフォームを含むことができるので、そうしてDLLを作成し、ソリューションエクスプローラから[参照設定]呼び出すDLLを設定すればDLLの中のフォームを呼び出すことができます。

もしもそうではなく、それぞれのプロジェクトが独立して動作できる.exeファイルをビルドするプロジェクトである必要がある場合、少々面倒な手続きを経てリフレクションを利用して操作を行うことになります。
詳しく書くと長くなる上、必要ないかもしれないのでごく簡単な例だけ示しておきます。

using System.Reflection;

Assembly asm = Assembly.LoadFile("project2.exe");
Form form = asm.CreateInstance("project2.Form1") as Form;
if(form != null)
{
form.Show();
}

余談になりますが、リフレクションは少々面倒ですが、これを利用すれば大変面白いことができるようになります(マイクロソフトのTerrariumなどがその例です)。
> Codingslaveさま

実現したい方法は後者だったのでサンプルを参考に動かしてみたら
きちんと動作しました。
ありがとうございます。
リフレクションについてもっと勉強しようと思います。

追加の質問で申し訳ないのですが…
後者でプロジェクトを移動した際(プロジェクトA→Bに遷移)、
前のプロジェクトのテキストなどの値を、遷移後のプロジェクトに
渡すためにはどのようにすればよろしいのでしょうか。

何度も質問してすいませんがよろしくお願いいたします。
> 後者でプロジェクトを移動した際(プロジェクトA→Bに遷移)、
> 前のプロジェクトのテキストなどの値を、遷移後のプロジェクトに
> 渡すためにはどのようにすればよろしいのでしょうか。
リフレクションで呼び出された側のフォームにデータを渡す方法を探しているのでしたら、インターフェイスや基本クラスを利用するという方法があります。

新たにクラスライブラリを作成するプロジェクトを作り、そこにインターフェイスを定義します。

public interface IFormManipulator
{
void Show();
void SetSomeText(string text);
}

これをビルドしてDLLを作成してください。
そして呼び出す側・呼び出す側の両方ともこのライブラリへの参照を追加し、さらに呼び出される側のフォームはこのインターフェイスを実装してください。Formから派生しているクラスであればすでにShow()は実装されていることになるので、SetSomeText()だけを実装してください(MessageBoxなどで渡されたテキストを表示するようにしておけばわかりやすいと思います)。

次に呼び出す側のコードに一部手を加えます。

using System.Reflection;

Assembly asm = Assembly.LoadFile("project2.exe");
IFormManipulator form = asm.CreateInstance("project2.Form1") as IFormManipulator;
if(form != null)
{
form.Show();
form.SetSomeText("テスト");
}

なにも問題がなければ「テスト」という文字列のメッセージボックスが表示されると思います。

必要な操作を持つインターフェイスや基本クラスを両者が共通して持っていればそれを通じて操作を行うことができます。
今回のようにアセンブリ間の通信を目的とした場合などにはクラスよりもインターフェイスを利用したほうが柔軟なコーディングが可能になります。
逆にクラスを利用すれば内部でセキュリティチェックが行えるので安全なコーディングが可能になります。
> Codingslaveさま
返事が遅れて申し訳ありませんでした。
投稿後、いろいろあって、結局1プロジェクト内でFormを切り分けて
データを受け渡すことになり、そちらを調べて試していたので、
せっかくの投稿内容を試す時間がありませんでした。
でも方法があることがわかり、今後に役立てたいと思います。
ご指導ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板