0

1 つのソリューションに 2 つのプロジェクトがproject Aあり、project B( using VS2010 Ultimate and C# windows application)。 Project Bのユーザー管理アプリケーションとして機能しますproject A。すべてのフォーム名とテキストをリストproject Bするコントロールを含むフォームがあります(このフォームにより、システム管理者は、セキュリティグループに基づいて表示/編集が許可されているフォームをユーザーに許可できます)これは私のコードです:chekcedlistboxproject A

   private void GetFormNames()
    {
        foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
        {
            foreach (Type t in a.GetTypes())
            {
                if (t.BaseType == typeof(Form))
                {
                    var emptyCtor = t.GetConstructor(Type.EmptyTypes);
                    if (emptyCtor != null)
                    {
                        var f = (Form)emptyCtor.Invoke(new object[] { });
                        string FormText = f.Text;
                        string FormName = f.Name;
                        checkedListBox1.Items.Add("" + FormText + "//" + FormName + "");
                    }
                }
            }

        }

    }

私が得ている結果は、現在のプロジェクトのフォーム名 (B) と空の行 (//) とSelect Window//MdiWindowDialog,PrintPreviewです。

4

3 に答える 3

1

あなたがProjectA正しく参照しており、関心のあるすべてのフォームが実際にはpublicパラメーターなしのコンストラクターを持っていると仮定します。ProjectAこの問題は、まだ読み込まれていないことが原因である可能性があります。これは複数の方法で修正できます。おそらく最も直接的な方法は、を使用することstatic Assembly.Loadです (ファイルが同じディレクトリにある限り、そうでない場合はより複雑になります)。

try
{
    Assembly projectA = Assembly.Load("ProjectA"); // replace with actual ProjectA name 
    // despite all Microsoft's dire warnings about loading from a simple name,
    // you should be fine here as long as you don't have multiple versions of ProjectA
    // floating around

    foreach (Type t in projectA.GetTypes())
    {
        if (t.BaseType == typeof(Form))
        {
            var emptyCtor = t.GetConstructor(Type.EmptyTypes);
            if (emptyCtor != null)
            {
                var f = (Form)emptyCtor.Invoke(new object[] { });
                // t.FullName will help distinguish the unwanted entries and
                // possibly later ignore them
                string formItem = t.FullName + " // " + f.Text + " // " + f.Name;
                checkedListBox1.Items.Add(formItem);
            }
        }
    }
}
catch(Exception err)
{
    // log exception
}

別の (おそらくよりクリーンな解決策) は、関心のあるすべてのフォームを単一の基本フォームから継承することです。次に、既知のものからアセンブリをロードし、リストに追加する前にType、列挙された各アセンブリがアセンブリからType継承されていることを確認できます。ただし、これはより広範な変更であり、ProjectA.

于 2013-04-20T12:37:21.793 に答える
0

このコードを試してください:

 private void GetFormNames()
    {


        Type[] AllTypesInProjects = Assembly.GetExecutingAssembly().GetTypes();
            for (int i = 0; i < AllTypesInProjects.Length; i++)
            {
                if (AllTypesInProjects[i].BaseType == typeof(Form))
                {            /* Convert Type to Object */
                    Form f = (Form)Activator.CreateInstance(AllTypesInProjects[i]);
                    string FormText = f.Text; 
                    listBox1.Items.Add(FormText);
                }
            }

    }
于 2013-04-20T11:50:07.280 に答える