2013-04-20 128 views
0

我在一个解决方案中有两个项目,分别为project Aproject Busing VS2010 Ultimate and C# windows application)。 Project B充当project A的用户管理应用程序。 在project B我有一个表格,其中包含一个chekcedlistbox控件,将列出所有project A表单名称和文本(此表单将允许系统管理员授予用户允许查看/编辑基于其安全组的表单) 这是我的代码:C#从项目B获取项目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//MdiWindowDialogPrintPreview格式的名称。

+0

而你的问题是?你期望有什么不同?你为什么这么认为? – rene 2013-04-20 09:57:04

+2

您是否在项目B中添加了项目A的程序集引用? – Blau 2013-04-20 11:28:12

+0

您是否检查我的答案 – Sathish 2013-04-22 05:56:45

回答

0

我会假设你已经正确地引用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

+0

谢谢杰里,你的解决方案工作完美 – WAA 2013-04-22 11:15:15

0
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 
foreach (Assembly a in assemblies) 
{ 
    Type[] types = a.GetTypes(); 
    foreach (Type t in types) 
    { 
     if (t.BaseType == typeof(Form)) 
     { 
        //Do Your works 
     } 
    } 
} 
+0

我不太确定您在这里提出的建议。是否在声明的变量中存储返回值'AppDomain.CurrentDomain.GetAssemblies()'和'a.GetTypes()'会有所作为?它肯定不会。你是说OP不应该改变'if'语句中的内容吗?如果是这样,你应该更清楚并举一个具体的例子。 – jerry 2013-04-20 12:14:22

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); 
       } 
      } 

    } 
+0

这将返回OP已经获取的表单的子集,它不会添加任何内容。 – jerry 2013-04-20 12:19:43

相关问题