Vb.net 动态打开窗体
我有一个叫做TopicBar的第三方控件,它看起来像WindowsXP导航栏,你可以在窗口的左侧看到 在我的应用程序中,我有71个表单,我创建了一个DB表来存储我的所有表单Vb.net 动态打开窗体,vb.net,forms,Vb.net,Forms,我有一个叫做TopicBar的第三方控件,它看起来像WindowsXP导航栏,你可以在窗口的左侧看到 在我的应用程序中,我有71个表单,我创建了一个DB表来存储我的所有表单名称和文本,部分用户可以添加哪些表单(通过搜索我已经存储在表中的表单名称)应作为项目添加到topicbar中 例如,一个名为FrmBill的表单,其名称为Bill一旦用户将Bill添加到Topicbar,它将成功创建一个名为Bill的项目,现在我面临的是,当该用户单击Topicbar中的Bill项目时,我需要打开表单FrmBi
名称
和文本
,部分用户可以添加哪些表单(通过搜索我已经存储在表中的表单名称)应作为项目添加到topicbar中
例如,一个名为FrmBill的表单,其名称为Bill一旦用户将Bill添加到Topicbar,它将成功创建一个名为Bill的项目,现在我面临的是,当该用户单击Topicbar中的Bill项目时,我需要打开表单FrmBill
我可以得到表单名ie FrmBill是一个用户点击账单,但我无法打开表单,因为我需要在这里动态创建实例或调用表单FrmBill
到目前为止我做了什么
Dim formName As String
Dim frm As Form
Using conn As New SqlConnection(conn_str)
conn.Open()
Dim cmd As SqlCommand
cmd = New SqlCommand("", conn)
cmd.CommandText = "select top 1 formname from winforms where id=" & winformid & ""
formName = cmd.ExecuteScalar
'output: FrmBill
frm = New Form
frm.Name = formName '(FrmBill)
With frm
.MdiParent = FrmMain
.Show()
.Focus()
End With
End Using
注意:在这个函数中,我可以从数据库中获取表单名称ieFrmBill
,但它不显示实际表单FrmBill
那么,有没有办法像下面这样声明表单名称
dim frm as new "& formname &"
它不像“dim frm as new”(dim frm as new)和formname&“”那么简单,但可以通过以下方式完成:
Dim frmNewForm As Form = Nothing
Dim frmNewForm_Type As Type = Type.GetType("your_assembly.type_name")
frmNewForm = CType(Activator.CreateInstance(frmNewForm_Type), Form)
我的意思是,你必须存储类表单的类型
编辑:
您可以打开一个表单,以便:
Dim oFr as New frmBill
oFr.Show()
好吗?好。您可以打开一个表单,以便:
Dim oFr as Form
oFr = New frmBill ' Because frmBill inherits System.Windows.Forms.Form class. All forms do it
oFr.Show()
在这里,frmBill是类的类型。您没有frmBill显式引用,因此必须以动态方式加载它
怎么办?使用一种称为反射的“网络机制”。您可以通过指定类类型来创建一个类
Dim frmNewForm As Form = Nothing
Dim frmNewForm_Type As Type = Type.GetType("project_name.frmBill")
frmNewForm = CType(Activator.CreateInstance(frmNewForm_Type), Form)
普卢图尼克斯在说什么?假设您在frmBill中有一个公共“Print”方法。根据我的回答,你不能这样做:
frmNewForm.print()
因为您只能访问System.Windows.Forms.Form方法(关闭、显示、显示对话框…)
您可以通过使用自定义基类、接口或基类抽象类来改进这一点。。。如你所需。你可以结合不同的想法,这取决于你需要什么。例如,可以将接口与超类组合:
public class frmMyForms
inherits System.Windows.Forms.Form
public sub store_data ()
现在,你可以做如下事情:
Dim frmNewForm As frmMyForms= Nothing
Dim frmNewForm_Type As Type = Type.GetType("project_name.frmBill")
frmNewForm = CType(Activator.CreateInstance(frmNewForm_Type), frmMyForms)
frmNewForm.Show()
frmNewForm.store_data()
ctype(frmNewForm, IInterface_common_methods).Print()
我不知道这是否是您正在寻找的,但我希望这可以帮助您了解更多有关网络可能性的信息。我想您可以使用
选择案例
,但它有点复杂。你需要创建71个案例才能在你的代码中工作我相信为了实现你想要的,你必须使用一个或类似的工具来实际存储表单本身(或至少是表单实例)。然后,您必须从表单的名称(这将是字典中的键)获取表单,并调用.Show()
。脱离主题:是否应该注释关闭的原因Vote@VisualVincent我需要像这样在字典中添加71个表单。添加(“FrmBill”,FrmBill),对吗?是的。您是正确的。这将导致窗体转换为Windows.System.Forms.form而不是此应用程序。FrmBill
任何FrmBill
方法或控件都将不可用accessible@Plutonix要调用一个方法,我将结合使用接口,或者通过反射(type.InvokeMember)调用它们,但作为提问者,它只是在寻找一场表演(),这可能就足够了,不是吗?我不是说这是错误的,只是有限的。具有71个特殊表单的应用程序可能希望在其上使用独特的控件/etc。@我同意that@Caveman我不能理解这可能是因为我缺乏VB.NET的知识
public class frmBill
inherits frmMyForms
implements IInterface_common_methods
public overloads sub store_data ()
msgbox ("store")
end sub
public sub print () implements IInterface_common_methods.print
msgbox ("print")
end sub
Dim frmNewForm As frmMyForms= Nothing
Dim frmNewForm_Type As Type = Type.GetType("project_name.frmBill")
frmNewForm = CType(Activator.CreateInstance(frmNewForm_Type), frmMyForms)
frmNewForm.Show()
frmNewForm.store_data()
ctype(frmNewForm, IInterface_common_methods).Print()