VisualBasic2005实现系统动态调用框架

    技术2022-05-11  79

         用VisualBaisc6 做数据库开发已经有多年,对于.net Framework却一向是“虽不能至,心向往之”。VisualBasic2005发布后,终于还是抽了一些业余时间去学习。结合以前系统开发的经验,想实现一个功能可以动态配置的系统框架,主要思路是将构成系统的三级(模块/功能组/功能)存储在数据库中,在系统的主界面上使用TreeView控件,从数据库中取得这三层的数据,生成一个树形菜单,然后用户单击最末端的功能结点时,根据相应的节点值调用相应窗口,即根据一个字符串来调用相应的窗口。这样做的好处是可以动态增减系统已具备的功能,如果不想把某个功能开放给用户,只需删除数据库中记录即可,某些规模较大的程序就是这样管理程序功能的。本来这种功能在PowerBuilder或VB6中都相当容易实现,但在用VB2005实现时,由于对系统的“反射”机制不熟悉,还是遇到了一些困难……

            在PB中,如果你打开窗口时用第二种语法,即Open ( windowvar, windowtype {, parent } ),把字符串变量(窗口名)传递给Open函数,则可得到指定窗口的一个实例,想做什么操作就容易了。在VB6中虽然没有这种机制,但用Forms集合遍历当前系统打开的所有窗口,也可以实现。后来查阅了VB2005的Forms,虽然能访问已打开的窗口,但却无法得到未打开的窗口。而本身我的意图就是想根据窗口名称来实例化一个窗口,这样肯定不行。后来在网上也找了一些资料,了解了反射(Reflection),也知道了可以根据程序集中存储的元数据来CreateInstance一个对象。但这一切的前提就是必须得得到这个对象相关的元数据,指定程序集什么的,这些代码我就不列出了,网上可以搜索到。但是问题我其实只想调用当前程序集里面的窗口,有没有简单一点的办法呢?

            后来突然想到,既然当前项目中所有的窗口都具有元数据信息,那么我只要先得到一个已知窗口的元数据信息,然后将其中的窗口名称替换成我要指定打开的窗口名称(利用字符串处理的形式),那不就可以动态实例这个窗口了吗?当时想到这里真是欣喜若狂(当然表明自己还是水平太低),于是马上写出了以下的过程:

        Private Sub OpenForm(ByVal FormName As String)        Try            Dim strName As String = GetType(MainForm).AssemblyQualifiedName            strName = strName.Replace("MainForm", FormName)            Dim TypeToLoad As Type = Type.GetType(strName)            Dim GenericInstance As Object            GenericInstance = Activator.CreateInstance(TypeToLoad)            Dim FormToShow As Form = CType(GenericInstance, Form)            FormToShow.MdiParent = MainForm            FormToShow.Show()        Catch e As ArgumentNullException            MsgBox("打开功能时出现错误,请检查功能是否已挂接,或检查名称" & FormName & "合法性。", MsgBoxStyle.Information, "提示")            'Catch e1 As Exception            '    MsgBox("未知错误,功能未能正常打开!", MsgBoxStyle.Information, "提示")        End Try    End Sub

            其中的MainForm是项目中的主窗口,肯定是存在的,我就以它的元数据为模板进行字符串处理了。得到元数据后要实例化也就易如反掌了。这时要实现动态调用,直接调用此过程即可。这样在树形的NodeMouseClick事件中写上OpenForm(e.Node.Tag)就万事大吉了(我将窗口名称填写在节点的tag属性中)。

            功能算是实现了,却不免有些投机取巧,毕竟还是写死了一个过程中的变量,对当前项目中的窗体是有依赖性的,而且我在使用中发现,要调用的窗口名称大小写还必须是和你在项目中所写的是完全一致的,否则会出错。因此,这确实不算是一个真正通用的函数,但碍于水平所限,目前还没有更好的方法,欢迎各位高人不吝指教,提出更好的实现思路。谢谢!

     


    最新回复(0)