Listing 1 shows the complete html for the EditPropertyDefinition.ascx file. It is immediately obvious that the html for this control is much simpler than most traditional "Edit Pages". Instead of a 9 row Table there is a single control declaration for the body of the control.
Listing 1: The EditPropertyDefinition.ascx File |
1: <%@ Control Inherits="DotNetNuke.Modules.Admin.Users.EditProfileDefinition"
CodeFile="EditProfileDefinition.ascx.vb" language="vb" AutoEventWireup="false"
Explicit="True" %>
2: <%@ Register TagPrefix="dnn" Assembly="DotNetNuke" Namespace="DotNetNuke.UI.WebControls"%>
3:
4: <dnn:propertyeditorcontrol id="Properties" runat="Server"
5: SortMode="SortOrderAttribute"
6: labelstyle-cssclass="SubHead"
7: helpstyle-cssclass="Help"
8: editcontrolstyle-cssclass="NormalTextBox"
9: labelwidth="200px"
10: editcontrolwidth="250px"
11: width="450px"/>
12: <p>
13: <dnn:commandbutton class="CommandButton" id="cmdUpdate"
imageUrl="~/images/save.gif" resourcekey="cmdUpdate"
runat="server" text="Update"/>
14: <dnn:commandbutton class="CommandButton" id="cmdCancel"
imageUrl="~/images/lt.gif" resourcekey="cmdCancel"
runat="server" text="Cancel" causesvalidation="False" />
15: <dnn:commandbutton class="CommandButton" id="cmdDelete"
imageUrl="~/images/delete.gif" resourcekey="cmdDelete"
runat="server" text="Delete" causesvalidation="False" />
16: </p>
|
The first line of XHTML is the standard ASP.NET declaration for a User Control. The second line registers the PropertyEditorControl which can be found in the Assembly - DotNetNuke and the Namespace - DotNetNuke.UI.WebControls. This registration information is commonly used in ASP.NET User Controls and tells the ASP.NET parser where to find the PropertyEditorControl.
The PropertyEditorControl is defined in Lines 4-11 of the ascx file, and the last few rows provide a row of Save, Delete and Cancel Command Buttons.
Lets look a little more closely at the PropertyEditorControl declaration. This is shown again in Listing 2.
Listing 2: The PropertyEditorControl Declaration
|
4: <dnn:propertyeditorcontrol id="Properties" runat="Server"
5: SortMode="SortOrderAttribute"
6: labelstyle-cssclass="SubHead"
7: helpstyle-cssclass="Help"
8: editcontrolstyle-cssclass="NormalTextBox"
9: labelwidth="200px"
10: editcontrolwidth="250px"
11: width="450px"/>
|
The first line defines the type of control (dnn:propertyeditorcontrol) the Id and whether the control is a server control. The second line tells the control to sort the rows based on the SortOrderAttribute. I will go into more detail on this in a later article. The remaining attributes define the styles to use for the Label, Help and EditControls, the widths to use for the Label column and Edit Column and the total width for the Property Editor.
The Code File (.ascx.vb)
Since there is very little to the ascx file, let's look at the associated code file for this UserControl. The Page_Load method is shown below in Listing 3.
Listing 3: The Page_Load method
|
1: Private Sub Page_Load(ByVal sender As System.Object, _
2: ByVal e As System.EventArgs) Handles MyBase.Load
3: Try
4: 'Declare Property Definition object
5: Dim propertyDefinition As ProfilePropertyDefinition
6:
7: If PropertyDefinitionId <> Null.NullInteger Then
8: 'Get Property Definition from Data Store
9: propertyDefinition = ProfileController._
10: GetPropertyDefinition(PropertyDefinitionId)
11: Else
12: 'Create New Property Definition
13: propertyDefinition = New ProfilePropertyDefinition
14: propertyDefinition.PortalId = PortalId
15: End If
16:
17: cmdDelete.Visible = True
18: ClientAPI.AddButtonConfirm(cmdDelete, _
19: Localization.GetString("DeleteItem"))
20:
21: 'Bind Property Definition to Data Store
22: Properties.LocalResourceFile = Me.LocalResourceFile
23: Properties.DataSource = propertyDefinition
24: Properties.DataBind()
25:
26: Catch exc As Exception 'Module failed to load
27: ProcessModuleLoadException(Me, exc)
28: End Try
29: End Sub
|
Again this is fairly straightforward. Lines 4-15 either fetch the Property Definition (if in edit mode) or create a new one and initialise the PortalId. Lines 22-24 then bind the Property Definition (ProfilePropertyDefinition) to the Property Editor control (id=Properties). You will notice that the Property Editor behaves like any "Data" control - the DataSource Property is set and then the DataBind method is called. In this case an additional property (LocalResourceFile) is also set so that the Property Editor correctly localizes the labels.
Listing 4 shows the cmdUpdate_Click method which saves the changes made by the administrator user.
Listing 4: The cmdUpdate_Click method
|
1: 'Check if Property Editor has been updated by user
2: If Properties.IsDirty And Properties.IsValid Then
3: 'Declare Definition and "retrieve" it from the Property Editor
4: Dim propertyDefinition As ProfilePropertyDefinition
5: propertyDefinition = DirectCast(Properties.DataSource, ProfilePropertyDefinition)
6:
7: If PropertyDefinitionID = Null.NullInteger Then
8: 'Add the Property Definition
9: PropertyDefinitionID = ProfileController.AddPropertyDefinition(propertyDefinition)
10: Else
11: 'Update the Property Definition
12: ProfileController.UpdatePropertyDefinition(propertyDefinition)
13: End If
14: End If
|
In Line 2 of this method the PropertyEditorControl instance (Properties) is checked to determine if there have been changes (Properties.IsDirty) and if the data is valid (Properties.IsValid). If the data has been updated the DataSource property of the control is retrieved and cast into a ProfilePropertyDefinition instance. The Profile Property Definition instance is then saved to the Data Store.
If you compare with this with many other "Edit" pages in DotNetNuke, this looks pretty straightforward. Both the amount of markup in the ascx file and the amount of code in the codefile are much smaller than in a conventional "Edit" page. One big advantage is that adding new "properties" to the class does not require any changes to either the "Page_Load" method or the cmdUpdate_Click method as neither of them refer specifically to individual properties of the class being edited. In this example the ascx file also does not require any changes.
This is just a simple example. The controls are very flexible and can be customized (and extended) extensively, which I will cover in future articles in this series.