【问题标题】:Dynamically Open form动态打开表单
【发布时间】:2015-10-28 12:21:51
【问题描述】:

我有一个名为 TopicBar 的第三方控件,它看起来像你可以在窗口左侧看到的 windows xp 导航栏

在我的应用程序中,我有 71 个表单,我创建了一个数据库表来存储我的所有表单 NameText,特定用户可以添加哪些表单(通过搜索我已经存储在表中的表单名称) 应作为项目添加到主题栏中。

例如,一个名为 FrmBill 的表单,它的名称是 Bill,一旦用户将 Bill 添加到 Topicbar,它将成功创建一个名为 Bill 的项目,现在我面临的是我需要在该用户单击时打开表单 FrmBill在主题栏中的账单项上

我可以获取表单名称,即 FrmBill 是用户在 Bill 中点击,但我无法打开表单,因为我需要在此处动态创建实例或调用表单 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

注意:在这个函数中,我可以从数据库中获取表单名称,即FrmBill,但它没有显示实际的表单FrmBill

那么无论如何都要像下面这样声明表单名称

dim frm as new "& formname &"

【问题讨论】:

  • 我猜你可以使用select case,但它有点复杂。您需要创建 71 个案例才能在您的代码中工作
  • 我相信,为了实现您正在寻找的内容,您必须使用dictionary 或类似于实际存储表单本身(或至少它们的实例)。然后你必须从它的名字中获取表格(这将是字典中的键)并调用.Show()
  • 离题:应该评论否决投票的原因
  • @VisualVincent 我需要像DicForms.Add("FrmBill", FrmBill) 这样在我的字典中添加 71 个表单,对吗?
  • 是的。你是对的。

标签: vb.net forms


【解决方案1】:

这并不像“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 显式引用,因此您必须动态加载它。

怎么可能呢?使用称为反射的“NET 机制”。您可以动态地创建一个类,指定类类型。

Dim frmNewForm As Form = Nothing
Dim frmNewForm_Type As Type = Type.GetType("project_name.frmBill")
frmNewForm = CType(Activator.CreateInstance(frmNewForm_Type), Form)

Plutonix 在说什么?假设您在 frmBill 中有一个公共的“打印”方法。
根据我的回答,你不能这样做:

frmNewForm.print()

因为你只能访问 System.Windows.Forms.Form 方法(close、show、showdialog...)

您可以根据需要使用自定义基类、接口或基本抽象类...来改进这一点。您可以根据需要组合不同的想法。例如,您可以将接口与超类结合起来:

public class frmMyForms
   inherits System.Windows.Forms.Form 

   public sub store_data ()  

....

public interface IInterface_common_methods

 sub print ()

...

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() 

我不知道这是否是您正在寻找的东西,但我希望这可以帮助您了解有关 NET 可能性的更多信息。

【讨论】:

  • 这将导致表单转换为Windows.System.Forms.Form 而不是thisApplication.FrmBill 任何FrmBill 方法或控件都将无法访问
  • @Plutonix 要调用一个方法,我会将其与接口使用结合起来,或者通过反射(type.InvokeMember)调用它们,但作为询问者,它只寻找一个 Show(),它可能是够了吧?
  • 我不是说错了,只是有限。具有 71 种特殊形式的应用程序可能希望在其上使用独特的控件/等。
  • @Plutonix 我同意这一点
  • @Caveman 我无法理解这可能是因为我缺乏 VB.NET 知识
猜你喜欢
  • 2014-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
相关资源
最近更新 更多