Introduction
Version 4.3 of the DotNetNuke Web Application Framework introduced a suite of Property Editors. These Property Editors dynamically inject the appropriate Edit Control depending on the Data Type to be edited. There are 5 types of editor and 47 class or enum files that make up the Property Editor suite of controls. This article provides an introductory overview to the new Property Editor.
The PropertyEditor
While a lot more attention has been focussed on the Profile Editor, there are 4 other editors in the Property Editor Suite of controls. This article will focus on the PropertyEditorControl. This control can be used to edit some or all of the properties of an instance of a class.
The beauty of this control is that the code required to set up an "Edit Page" for an object becomes much simpler. This doesn't mean that the editor is less flexible than the traditional way of creating an Edit Page, in fact the new PropertyEditor provides a lot more flexibility, as it can take advantage of the full suite of EditControls, provided in the DotNetNuke core, as well as custom EditControls created by 3rd parties.
| Figure 1: Adding a new Profile Property |
 |
We will describe how this control can be used by discussing a real example that is found in the DotNetNuke core - the "Edit Profile Definition " page (see Figure 1).
We have seen how this page works in earlier articles in this series, as it is used to manage the Profile Property Definitions used by the Profile Editor. It is important to note here that there are 9 properties managed on this page of three different types - text, combo/list, boolean/checkbox.
The ASCX File
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. We will go into more detail on this later in the 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 Proeprty 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 either saved to the Data Store.
Controlling the Behaviour of the Editor with Attributes
| Figure 2: PropertyEditor Attributes |
 |
So far we have seen how the editor is loaded and how the data in the editor is retrieved when the Update button is clicked. But how does the editor know to use a particular control to edit the data for a property and how does it know what properties are required.
In the Profile Editor discussed in an earlier article in this series, this is controlled by the various fields of the ProfilePropertyDefinition. In the case of the PropertyEditorControl this behaviour is controlled by Attributes. In .NET Attributes can be used to "decorate" a Property providing an extensible set of additional information about a property.
The Property Editor provides a set of custom Attributes that can be used to control the behaviour of the PropertyEditorControl (see Figure 2).
For example the IsReadOnlyAttribute can be used to make sure that the property is not editable, while the RequiredAttribute is used to identify a property that must have its value set.
Listing 5 shows the DataType property decorated with a 5 Attributes (Note that you can drop the Attribute from the name when applying attributes eg. List = ListAttribute).
| Listing 5: Applying Attributes to a Property |
1: <Editor("DotNetNuke.UI.WebControls.DNNListEditControl, DotNetNuke", _ 2: GetType(DotNetNuke.UI.WebControls.EditControl)), _ 3: List("DataType", "", ListBoundField.Id, ListBoundField.Value), _ 4: IsReadOnly(True), Required(True), SortOrder(1)> _ 5: <XmlIgnore()> Public Property DataType() As Integer 6: Get 7: Return _DataType 8: End Get 9: Set(ByVal Value As Integer) 10: If _DataType <> Value Then _IsDirty = True 11: _DataType = Value 12: End Set 13: End Property |
- Editor - allows you to control the EditControl used to edit the field. If not defined the PropertyEditor uses the default (TextBox)
- List -as the Edit Control defined is a List, this attribute provides the details on how to get the List.
- IsReadOnly - if the field has a value, ie. it is being edited rather than created, then this property is readonly
- Required - the user must provide a value
- SortOrder - the order of the property in the display.
In addition to creating your own controls you can create your own attributes. All attributes attached to the property are passed to the EditControl, so if you develop a custom EditControl for your own custom Info class you can also create and use your own attribute.
Conclusion
This article provides an overview of the new Property Editor introduced in DotNetNuke v4.3. It describes how to use it to edit an instance of a DotNetNuke Info class, and how to decorate the Info class with Attributes to control the editor.
About the Author: Charles Nurse is the owner of Keydance Computer Services, the sponsor of this site, as well as being a Trustee and Lead Developer in the DotNetNuke project.