您的位置:首页 > 其它

在DNN模块中如何调用DNN/Controls下的用户控件

2007-01-09 20:59 337 查看
最近在基于DNN开发一个网站,发现一件有趣的事情。
由于业务逻辑有许多可以抽取的共性,我将一个用于筛选的功能做成了用户控件(UserControl,为了方便叙述,我们称它为Filter),并把它放在DNN的Controls目录下,即\DotNetNuke\controls,以便各个模块均可调用。这个用户控件很简单,就是一些下拉框,用于对数据进行查询,我将下拉框的SelectedValue封装成公共属性,这样就可以从外部调用了。比如,里面的一个属性是这样写的:
'项目名称
Public Property ProjectName() As String
Set(ByVal Value As String)
_ProjectName = Value
End Set
Get
Return Me.sltProjectName.SelectedValue
End Get
End Property
这是几句VB.NET代码,当读取这个公共属性的时候,我就返回相应的下拉框(sltProjectName)的选中值(SelectedValue)。
很简单。

然后在自己编写的DNN模块(DesktopModules)中,这样使用它:
1、首先,在VS的“HTML”视图中,在顶部添加对它的引用:
<%@ Register TagPrefix="dnn" TagName="CSBSGFilter" Src="~/controls/CSBSGFilter.ascx" %><%@ Register TagPrefix="dnn" TagName="CSBSGFilter" Src="~/controls/CSBSGFilter.ascx" %><%@ Register TagPrefix="dnn" TagName="Filter" Src="~/controls/Filter.ascx" %>
2、然后,在HTML中合适的位置,添加一个引用实例,比如在一个单元格中:
<TD><dnn:Filter id="filter" runat="server"></dnn:Filter></TD>
3、OK,这样我已经在页面上加入了该用户控件,切换到“设计”视图,发现显示也正常,控件上没有红色粗体字体提示说“创建控件时出错”。
4、下面该开始书写代码了,我得调用这个用户控件的公共属性做事吖,否则我写它干什么?于是,切换到代码页,在类体中创建一个该用户控件的私有实例:
DotNetNuke.UI.UserControls.Filter filter = new DotNetNuke.UI.UserControls.Filter();
是的,这句话是要手工加上的,因为用户控件不像VS工具箱里面的Label、Button一样,只要拖到页面上,代码中就会创建一个实例。
5、到现在为止,一切都很正常。下面一句调用该用户控件的公共属性:
string projectName = filter.ProjectName;
这看起来也没有什么问题,公共属性嘛,可以调用。编译的时候也通过了,但运行的时候,读取用户控件的属性值之后,点击“提交”按钮时,DNN却捕获了异常,经典错误:“未将对象设置引用到对象实例”。

怎么回事?经过调试、跟踪,发现当页面装载的时候,用户控件里面的下拉框们还都正常(因为我在用户控件的PageLoad事件中对它们进行了绑定),但“提交”(指的是调用用户控件的页面提交)时,在Button的Click事件中,执行上述第5步操作时,引发了该异常,继续跟下去,发现当我欲:
Return Me.sltProjectName.SelectedValue
的时候,下拉框控件sltProjectName适时地变成了NoThing……

我@-@~~了。怎么回事?页面装载时绑定它们还正常,怎么一提交就没有了?(注意,由于其他原因,我没有让下拉框AutoPostback = true)
后来经过高手的指点,告知原因出在创建实例的这句话:
DotNetNuke.UI.UserControls.Filter filter = new DotNetNuke.UI.UserControls.Filter();
把它改成仅声明,不进行new操作:
DotNetNuke.UI.UserControls.Filter filter;
直到需要的时候用这种形式去获取对象实例:
filter = this.FindControl("filter") as Filter;
然后再调用属性,就正常了。
原因是什么?据高手说,这句话看上去虽然很无辜,但由于在HTML代码中已经写了:
<dnn:Filter id="filter" runat="server"></dnn:Filter>
这就相当于已经创建了一个实例,只需声明一下,与之匹配上就可以了,而这句话又创建了一个实例,覆盖了原本存在的那个,就导致了错误。(大致如此罢,我没有搞很明白,这块挺复杂的)
总之,记在这里罢,究竟是什么原因,欢迎大家拍砖。以后有相同迷惑的朋友也可以做一个参考,遇到这种情况百思不得其解的时候,试试这种方法,或许能够解决。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐