在前边一篇文章里简单说明了如何利用labelControl达到dnn的物尽其用,如果感兴趣的话,不妨看看,在此我继续上次的话题,稍微深入的了解一下UrlControl.我想做模块开发者都比较熟悉这一控件吧,在上传文件(比如图象)或链接页面(外部或本站点页面)都可以直接使用这一控件,可节省很多代码量及其工作量。今儿我就不在详细说明如何使用这一控件,而是主要专注如何修改urlControl以达到我们的需要。比如我想直接这一控件实现图片预览的功能,也就是当用户选择不同文件或者不同图片时,旁边某一区域也显示这一图片的预览图(或是缩略图),如此一来用户能比较清晰知道目前所选的图片,当然对应在用户上传成功之后也应该显示预览图。
需求如上,大家暂时先想想在dnn里边该如何来实现这样的功能呢,尤其是直接利用UrlControl?因为UrlControl本身封装的控件里边有些属性(比如其中包含的某一控件)你是直接访问不到的,就比较类似的上篇文章提到的cmdHelp属性(Protected)。不妨先看看源代码:

从这些属性中我们就可以暂时构造出图象预览图控件的原型,页面代码如下:
<td>
<portal:url id="ctlImageURL" runat="server" width="200" urltype="F" FileFilter="jpg,gif,png" ShowTrack="false" ShowLog="false" ShowTabs="false" ShowUrls="false"/>
<asp:Image id="imgPreview" runat="server" style="margin-left:10px;"/>
</td>
因为我们只需要可以上传图片并有预览功能的控件,所以一些不必要的功能就直接摒弃了,比如ShowTabs, ShowTrack, ShowUrls等等,然后加入过滤图片的类型这一属性FileFilter即可,当然另外加入一图像控件作为预览的载体。好了,那接下来就是如何添加用户响应事件,比如改变文件夹时图片的变化,图片选择时产生的变化及其上传图像成功时所激发的变化。我们也知道Url默认是已经有这些事件了,可是现在我们想附加额外的事件,你觉得可行么?应该可行吧?^_^我们还是再看看源代码,仔细看看你会发现Url有这一属性cboFolders,它对应就是里边文件夹选择控件,不过很不幸,它是Protected,你无法直接访问:
Protected Overridable Property cboFolders() As DropDownList
Get
Return Me._cboFolders
End Get
Set(ByVal WithEventsValue As DropDownList)
If (Not Me._cboFolders Is Nothing) Then
RemoveHandler Me._cboFolders.SelectedIndexChanged, New EventHandler(AddressOf Me.cboFolders_SelectedIndexChanged)
End If
Me._cboFolders = WithEventsValue
If (Not Me._cboFolders Is Nothing) Then
AddHandler Me._cboFolders.SelectedIndexChanged, New EventHandler(AddressOf Me.cboFolders_SelectedIndexChanged)
End If
End Set
End Property
你再琢磨琢磨,你会发现原来里边的事件是如何添加到对应的控件上的,那就是AddHandler 和RemoveHandler的魔力。那我们应该怎么改造呢,首先就是需要找到对应的控件(还是利用我上篇文章的方法),然后附加我们自己的业务事件,代码如下(仅供参考):
Private Sub AddHandlerToCboFile()
Dim target As DropDownList = CType(ctlImageURL.FindControl("cboFiles"), DropDownList)
target.AutoPostBack = True
AddHandler target.SelectedIndexChanged, New EventHandler(AddressOf Me.cboFiles_Changed)
Dim targetFolder As DropDownList = CType(ctlImageURL.FindControl("cboFolders"), DropDownList)
AddHandler targetFolder.SelectedIndexChanged, New EventHandler(AddressOf Me.cboFiles_Changed)
Dim targetSave As LinkButton = CType(ctlImageURL.FindControl("cmdSave"), LinkButton)
AddHandler targetSave.Click, New EventHandler(AddressOf Me.cboFiles_Changed)
End Sub
那对应的事件如何定义呢?其实很简单,跟其他事件定义并没二样:
Private Sub cboFiles_Changed(ByVal sender As Object, ByVal e As EventArgs)
Dim fileID As Integer = GetImageFileID()
ShowImage(fileID)
End Sub
Private Function GetImageFileID()
Dim nFileID As Integer = -1
If Not String.IsNullOrEmpty(ctlImageURL.Url) Then
Dim strArr() As String = ctlImageURL.Url.Split("="c)
nFileID = Integer.Parse(strArr(1).ToString())
End If
Return nFileID
End Function
Private Sub ShowImage(ByVal FileID As Integer)
Dim objController As FileController = New FileController()
Dim image As FileInfo = objController.GetFileById(FileID, PortalId)
If Not image Is Nothing Then
imgPreview.ImageUrl = LinkClick("fileid=" + FileID.ToString(), PortalSettings.ActiveTab.TabID, Null.NullInteger)
Utility.CreateThumbnail(image, imgPreview, Convert.ToInt32(_NewsSettings("MaxImageWidth")), Convert.ToInt32(_NewsSettings("MaxImageHeight")))
imgPreview.Visible = True
Else
imgPreview.Visible = False
End If
End Sub
这就是UrlControl全部的修改,基本上可以满足我们之前提到的需要,还是很多地方待改善的,接下来就是你的能力了.说到这,其实我想说的还是那句话:dnn本身有很多东西你可以直接为你所用,关键看你怎么用,原不愿意深入读代码? Please enjoy your developing journey with dnn.