www.dnnworkflow.cn

基于DotNetNuke的动态窗体支持(二)


    上文中我们提到,希望动态窗体的格式等全部可以由用户进行设定,这样,用户可以有最大的灵活性,于是,最终,我们的Form文件看起来可能是这样的:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
<!--
.STYLE3 {
    font-family: "宋体";
    font-size: 12px;
}
.STYLE4 {
    font-family: "宋体";
    font-size: 24px;
    font-weight: bold;
}
.STYLE6 {
    font-family: "幼圆";
    font-size: 36px;
}
-->
</style>
</head>

<body>
<font size="+3"><asp:PlaceHolder runat="server" ID="__RowName"></asp:PlaceHolder>    <!--标题--></font>
<hr />
<table width="730" border="0" cellpadding="0" cellspacing="0" class="STYLE3">
  <tr>
    <td align="center">(发布:<asp:PlaceHolder runat="server" ID="__Text1"></asp:PlaceHolder>    <!--发布人-->&nbsp;&nbsp;时间:<asp:PlaceHolder runat="server" ID="__Text2"></asp:PlaceHolder>    <!--发布时间-->)</td>
  </tr>
  <tr>
    <td>&nbsp;
              <asp:PlaceHolder runat="server" ID="__Content"></asp:PlaceHolder>
              <!--新闻内容-->    </td>
  </tr>
</table>   
<!--新闻内容-->
</body>
</html>

    这是一个用DreamWeaver制作的网页文件,美工完全可以完成;在完成之后,在特定的地方,插入我们的标识符, 也就是PlaceHolder控件,那么,当服务器加载完这个用户控件之后,对其子控件进行遍历,并且为我们的PlaceHolder控件增加适当的子控 件就可以了,这是实现User Defined Form的总体思路。我们的目的就是,希望通过这样的方式,可以让用户自己就可以定义界面;而不是通常情况下DotNetNuke的UDT模块所产生的很死板的录入界面。

    当然,这里马上就会有一个问题:如果是我们在开发的时候定义好的界面,比如一个添加了Text1文本控件的ascx文 件,我们在页面保存的时候,当然可以采用Text1.Text等方式来读取文本框的内容;但是,如果是动态页面的话,我们的控件是在运行的时候产生的,而 不是设计时。所以,我们在产生控件的时候,就必须要将之放到一个控件数组或者其他的方式存储,这样,我们在进行Save等动作的时候,就可以从控件数组 (或者其他的存储形式)中获取到该控件以及内容,并且保存到数据库中。

    在这里,我认为UserDefinedTable的方式非常好,定义了一个对象集合,具体的代码,大家可以下载UDT3.3.7以上的版本,找到EditControls.vb文件自行研究一下,下面是部分代码:

    Public Class EditControls
        Inherits System.Collections.CollectionBase

        Private parentModule As Entities.Modules.PortalModuleBase

        Public Sub New(ByVal ParentModule As Entities.Modules.PortalModuleBase)
            Me.parentModule = ParentModule
        End Sub

        Public Function Add(ByVal FieldTitle As String, ByVal FieldType As String, ByVal FieldID As Integer, _
                            ByVal Value As String, ByVal Required As Boolean, ByVal ExtendedSettings As String) As EditControl
            Dim Editor As EditControl
            Select Case FieldType
                Case "CreatedBy"
                    Editor = New EditCreatedBy(FieldTitle, FieldType, FieldID, Value, Required, ExtendedSettings)
            End Select
            MyBase.List.Add(Editor)
            Return CType(Editor, EditControl)
        End Function

        Default Public ReadOnly Property Item(ByVal Fieldtitle As String) As EditControl
            Get
                Dim i As Integer = 0
                Dim ec As EditControl
                Do
                    ec = CType(MyBase.List.Item(i), EditControl)
                    i += 1
                Loop Until ec.FieldTitle = Fieldtitle Or i > MyBase.List.Count
                If i > MyBase.List.Count Then Throw New ApplicationException("No EditControl found for " & Fieldtitle)
                Return ec
            End Get
        End Property
    End Class

    好了,整体的思路就是:
    
    我们让用户使用网页编辑工具定义窗体,并且约定窗体中包含有我们预定义的控件;【尽量灵活】
    在页面加载的时候,动态加载页面并且动态创建控件;【尽量让定义简单】
    所创建的控件,保存在我们约定的集合中,这样,在页面进行Post的时候,我们就可以读取到动态创建的控件,以便将控件的内容保存到数据库中。【保留我们创建的内容】

    以上,就是我们做自定义窗体的总体思路。

    下面的章节,我们看一下如何创建控件,以及如何扩展控件;以及控件如何自己进行行为约束等。
 posted on 2008-10-22 23:43  DnnWorkflow  阅读(220)  评论(0编辑  收藏  举报