在运行时从数据库名称 C# 实例化窗口表单
本文关键字:实例化 窗口 表单 运行时 数据库 | 更新日期: 2023-09-27 17:55:52
我在 c# 中实例化一个表单时遇到问题,我从数据库中检索其名称,我已经完全消除了命名空间,只是为了确保我没有弄错对象名称,但每次代码运行时,对象都返回为 null 而不是适当的形式。
private static Object CreateObjectInstance(string strObjectName)
{
Object obj = null; // Temporary object
try
{
if (strObjectName.LastIndexOf(".") == -1) // If there is no '.' in the object name
strObjectName = Assembly.GetEntryAssembly().GetName().Name + "." + strObjectName;
obj = Assembly.GetEntryAssembly().CreateInstance(strObjectName);
}
catch (Exception ex)
{
clsAdmFunctions.RecordException(ex); // Record error to the database
MessageBox.Show("Error instantiating the object'n'nDescription : "+ex.Message, "Object Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
obj = null;
}
return obj;
}
public static Form CreateForm(string strFormName)
{
return (Form)CreateObjectInstance(strFormName);
}
问题在于你的想法,即程序集名称是类名的一部分。诚然,您需要访问程序集,但最终类名只是Namespace.Class
名称。如果随类一起提供实际命名空间,则它可以工作。将您的方法更改为此方法,也许:
private static T CreateInstance<T>(string fullyQualifiedClassName)
{
try
{
return (T)Activator.CreateInstance(Type.GetType(fullyQualifiedClassName));
}
catch (Exception ex)
{
clsAdmFunctions.RecordException(ex); // Record error to the database
MessageBox.Show("Error instantiating the object'n'nDescription : " + ex.Message, "Object Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return default(T);
}
}
换句话说,如果要将命名空间保存在数据库中,也需要命名空间。只需这样保存class.GetType()
这样或class.GetType().ToString()
,之后您将看到命名空间也已保存。原因是在同一程序集中可以具有相同名称、namespace1.Person
和namespace2.Person
的类。
如果需要读取程序集中的所有命名空间,可以执行以下操作:
foreach(var type in Assembly.WhateverAssembly().GetTypes())
//print type.Namespace;
如果您不知道确切的命名空间,您将陷入困境。也许你可以假设它是
var namespace = Assembly.WhateverAssembly().GetTypes()[0].Namespace;
您需要为类提供命名空间,否则将反对 .NET的设计。如果你真的想你的 Forms 没有命名空间,你只需要指定类名,排除程序集名称。只需致电:
CreateInstance<MyForm>("MyForm");
前提是MyForm
global
并且程序集相同。如果窗体位于不同的程序集中,则首先使用 Assembly.Load
或 Assembly.LoadFrom
加载它,然后创建实例。
您的密钥方法CreateObjectInstance
应该可以正常工作,所以我猜是传入的参数?在我的示例中,我展示了如何包含完整的命名空间和类名等:
namespace Example.SubFolder
{
internal class frmAdmAbout
{
public string Name { get; set; }
}
}
namespace Example.ActualApp
{
using System;
using System.Reflection;
internal class Program
{
static void Main(string[] args)
{
var newItem = CreateObjectInstance("Example.SubFolder.frmAdmAbout");
if (newItem == null)
{
Console.WriteLine("Failed to create!");
}
else
{
Console.WriteLine("Successfully created!");
}
Console.ReadKey();
}
private static Object CreateObjectInstance(string strObjectName)
{
Object obj = null;
try
{
if (strObjectName.LastIndexOf(".") == -1)
strObjectName = Assembly.GetEntryAssembly().GetName().Name + "." + strObjectName;
obj = Assembly.GetEntryAssembly().CreateInstance(strObjectName);
}
catch (Exception ex)
{
Console.WriteLine("Error instantiating the object'n'nDescription : " + ex.Message);
obj = null;
}
return obj;
}
}
}