Please help: Multi-Interface Module

Last post 11-21-2005 6:57 PM by workcontrol. 4 replies.

Sort Posts:

  • Please help: Multi-Interface Module

    11-18-2005, 1:11 PM
    • Member
      245 point Member
    • NDLanding
    • Member since 09-29-2005, 4:17 PM
    • Posts 56
    Hi,

    I've been bashing my head against a brick wall on this all day - please could somebody show me how its done.

    I want to create a multi-interface module. I know I have to create my module as a user control according to DNN requirements. I was thinking of trying to develop a user control which acts as a container for other user controls (i.e. the various interfaces). These various interfaces would get loaded according to certain parameters using the LoadControl method. In the spirit of reusability I was also hoping to develop a menu user control (menu.ascx) which would also sit in the container. The thing is I'm having real problems getting the various constituents parts "talking" to each other and maintaining their state. I've developed 2 very simple interface or user controls - essentially each one comprises of a text box, label and a button (call them usercontrolA.ascx and usercontrolB.ascx. My menu control comprises of two links - essentially clicking on either one is supposed to load the appropriate control (i.e. usercontrolA.ascx or usercontrolB.ascx) into the container control (container.ascx). When the button on the usercontrolA.ascx or usercontrolB.ascx is clicked all it does is simply print out the contents of the textbox to the label underneath. I can't get it to work though - I never get to see anything on the label - it just seems to be reloading the control again.

    Please, if somebody has done somthing similar could they give me hand. I've tried looking at the forums module but it is way over my head. Furthermore how does a parent user control communicate with a child user control and vice versa?

    Thanks,

    Norm 
  • Re: Please help: Multi-Interface Module

    11-18-2005, 8:39 PM
    • Contributor
      2,385 point Contributor
    • imagemaker
    • Member since 03-26-2004, 8:57 PM
    • Maine
    • Posts 466
    I've just done this with my first DNN module which has 4 child viewcontrols (.ascx) which are loaded on demand into the parent control via LoadControl.  Here are a few pointers:
    1. Define a base class which inherits from PortalModuleBase and from which all the child controls (and possibly the parent as well) inherit.
    2. Pass the parent's ModuleConfiguration to the child control to allow the child to access the same properties such as TabModuleID, Settings, etc.
    3. Expose public properties and methods in the child control's code to allow the parent to communicate to the child.
    4. Expose public properties in the parent (or better yet define events in the child and event handlers in the parent) to allow the child to communicate to the parent.

    Here is a bit of code from the parent where the child control is loaded and its properties set:
          Select Case View
               Case "STD"
                  _ViewControl = CType(LoadControl(ModulePath & "Centers_Standard.ascx"), Centers_Standard)
               Case "RPT"
                  _ViewControl = CType(LoadControl(ModulePath & "Centers_Report.ascx"), Centers_Report)
               Case "WEB"
                  _ViewControl = CType(LoadControl(ModulePath & "Centers_Websites.ascx"), Centers_Websites)
               Case "EML"
                  _ViewControl = CType(LoadControl(ModulePath & "Centers_EMails.ascx"), Centers_EMails)
           End Select
           If Not _ViewControl Is Nothing Then
               _ViewControl.ModuleConfiguration = Me.ModuleConfiguration
               AddHandler _ViewControl.RefreshRequested, AddressOf ViewControl_RefreshRequested
               phView.Controls.Add(_ViewControl)
               _ViewControl.DataSource=GetData()
               _ViewControl.DataBind()
           End If
    



    Note that a public event "RefreshRequested" has been defined in the child control and an event handler attached in the parent.  Although this particular event passes no information back to the parent (other than a request to load new data into the child), it is appropriate to pass as much information as you need in the event by defining your own custom event argument classes inheriting from EventArgs.
    Bill, WESNet Designs
  • Re: Please help: Multi-Interface Module

    11-21-2005, 4:58 AM
    • Member
      245 point Member
    • NDLanding
    • Member since 09-29-2005, 4:17 PM
    • Posts 56

    Hi imagemaker,

    Thanks for the response. Is there any chance you could share some more code (i.e. that of the parent and a single simple child control). It sounds exactly like what I need but I have so many questions about the steps that you suggested I think it would be easier for you. For example here are some I have

    What's in the base class you mention in step 1?
    How and where (what event) do I pass the parent's ModuleConfiguration to the child control?
    Where do I put the code you posted i.e. in the Page_load event of the parent etc?
    How do construct event handlers?

    I'd really appreciate your continued assistance.

    Thanks,

    Norm

  • Re: Please help: Multi-Interface Module

    11-21-2005, 8:24 AM
    • Contributor
      2,385 point Contributor
    • imagemaker
    • Member since 03-26-2004, 8:57 PM
    • Maine
    • Posts 466
    Glad to be of help . . .

    The base class for both the child and parent controls contains mostly properties and functions for determining permissions. Note that it inherits from PortalModuleBase:


    Imports DotNetNuke
    Imports DotNetNuke.Security
    
    Namespace DotNetNuke.Modules.WESNet.Centers
    
        Public Class Centers_Base
            Inherits DotNetNuke.Entities.Modules.PortalModuleBase
    
    #Region "Private Members"
            Private _IsAdministrator As Int16 = -2
            Private _IsInEditRoles As Int16 = -2
            Private _DataSource As Object
    #End Region
    
    #Region "Public Properties"
    
            Public Property DataSource() As Object
                Get
                    Return _DataSource
                End Get
                Set(ByVal Value As Object)
                    _DataSource = Value
                End Set
            End Property
    
            'Perform a tri-State check to avoid repeated calls to IsInRoles
    
            Private ReadOnly Property AddRequiresApproval() As Boolean
                Get
                    If Not Settings("addapproval") Is Nothing AndAlso CType(Settings("addapproval"), String).Length > 0 Then
                        Return CType(Settings("addapproval"), String) = "Y"
                    Else
                        Return True
                    End If
                End Get
            End Property
    
            Private ReadOnly Property EditRequiresApproval() As Boolean
                Get
                    If Not Settings("editapproval") Is Nothing AndAlso CType(Settings("editapproval"), String).Length > 0 Then
                        Return CType(Settings("editapproval"), String) = "Y"
                    Else
                        Return True
                    End If
                End Get
            End Property
    
            Public ReadOnly Property DeleteAllowed() As Boolean
                Get
                    If Not Settings("deleteallowed") Is Nothing AndAlso Not CType(Settings("deleteallowed"), String) Is Nothing Then
                        Return CType(Settings("deleteallowed"), String) = "Y"
                    Else
                        Return True
                    End If
                End Get
            End Property
    
            Public ReadOnly Property IsAdministrator() As Boolean
                Get
                    If _IsAdministrator = -2 Then
                        _IsAdministrator = Convert.ToInt16(PortalSecurity.IsInRoles(PortalSettings.ActiveTab.AdministratorRoles) _
                                                             Or PortalSecurity.IsInRoles(PortalSettings.AdministratorRoleName))
                    End If
                    Return Convert.ToBoolean(_IsAdministrator)
                End Get
            End Property
    
            Public Function IsCreator(ByVal CreatedBy As Integer) As Boolean
                IsCreator = (CreatedBy = UserId)
            End Function
    
            Public ReadOnly Property IsInEditRoles() As Boolean
                Get
                    Dim rolestring As String
                    If _IsInEditRoles = -2 Then
                        rolestring = CType(Settings("editroles"), String)
                        If Not rolestring Is Nothing Then
                            _IsInEditRoles = Convert.ToInt16(Security.PortalSecurity.IsInRoles(rolestring) And IsEditable())
                        End If
                    End If
                    Return Convert.ToBoolean(_IsInEditRoles)
                End Get
            End Property
    
            Public Function CanEdit(ByVal CreatedBy As Integer) As Boolean
                CanEdit = (IsCreator(CreatedBy) AndAlso IsInEditRoles()) Or IsAdministrator()
            End Function
    
            Public Function CanDelete(ByVal CreatedBy As Integer) As Boolean
                CanDelete = (IsCreator(CreatedBy) AndAlso IsInEditRoles() AndAlso DeleteAllowed) Or IsAdministrator()
            End Function
    
            Public ReadOnly Property CanAdd() As Boolean
                Get
                    Return (IsInEditRoles() Or IsAdministrator()) And IsEditable
                End Get
            End Property
    
    #End Region
    
    #Region "Private Methods"
    
    #End Region
    
    #Region "Public Methods"
    
            Public Overridable Sub BindView()
    
            End Sub
    
            Public Overridable Sub RefreshView()
                RaiseEvent RefreshRequested(Me, New System.EventArgs)
            End Sub
    
            Public Function FormatImage(ByVal ImageFile As String) As String
                Try
                    If ImageFile.Length = 0 Then
                        FormatImage = String.Empty
                    Else
                        FormatImage = PortalSettings.HomeDirectory & ImageFile
                    End If
                Catch exc As Exception    'Module failed to load
                    ProcessModuleLoadException(Me, exc)
                End Try
            End Function
    
    #End Region
    
    #Region "Events"
            Public Event RefreshRequested As EventHandler
    #End Region
    
        End Class
    End Namespace
    

    Here's part of the codebehind for one of the child controls:

    Imports DotNetNuke
    Imports System.Web.UI.WebControls
    Imports DotNetNuke.Common
    Imports DotNetNuke.Security
    Imports System.Text
    
    Namespace DotNetNuke.Modules.WESNet.Centers
    
        Public MustInherit Class Centers_Standard
            Inherits DotNetNuke.Modules.WESNet.Centers.Centers_Base
            Implements Entities.Modules.IActionable
            Protected WithEvents btnAddCenter As System.Web.UI.WebControls.Button
    
    #Region "Controls"
            Protected WithEvents dgCenters As System.Web.UI.WebControls.DataGrid
    #End Region
    
            Public Function DetailURL(ByVal KeyName As String, ByVal KeyValue As String) As String
                If KeyName <> "" And KeyValue <> "" Then
                    Return NavigateURL(PortalSettings.ActiveTab.TabID, "Detail", "mid=" & ModuleId.ToString, KeyName & "=" & KeyValue)
                Else
                    Return NavigateURL(PortalSettings.ActiveTab.TabID, "Detail", "mid=" & ModuleId.ToString)
                End If
            End Function
    
            Public Overrides Sub BindView()
                If Not DataSource Is Nothing Then
                    dgCenters.DataSource = DataSource
                    dgCenters.Columns(8).Visible = IsAdministrator()
                    dgCenters.DataBind()
                End If
            End Sub
    
    #Region "Event Handlers"
    
            Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
                Try
                    If Not IsPostBack Then
                        BindView()
                    End If
                    btnAddCenter.Visible = CanAdd()
                Catch exc As Exception 'Module failed to load
                    ProcessModuleLoadException(Me, exc)
                End Try
            End Sub
    
            Private Sub dgCenters_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles dgCenters.ItemCreated
                If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
                    Dim ctl As ImageButton
                    ctl = CType(e.Item.FindControl("deleteCenter"), ImageButton)
                    If Not ctl Is Nothing Then
                        ctl.Attributes.Add("onClick", "javascript:return(confirm('Are you sure you want to delete this Center?'));")
                    End If
                End If
            End Sub
    
            Private Sub dgCenters_DeleteCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dgCenters.DeleteCommand
                Dim CenterID As Integer
                CenterID = CInt(e.CommandArgument)
                If CenterID > 0 Then
                    Dim ctlr As New CenterController
                    ctlr.DeleteCenter(CenterID)
                End If
                RefreshView()
            End Sub
    #End Region
    
    #Region "Optional Interfaces"
    
            Public ReadOnly Property ModuleActions() As Entities.Modules.Actions.ModuleActionCollection Implements Entities.Modules.IActionable.ModuleActions
                Get
                    Dim Actions As New Entities.Modules.Actions.ModuleActionCollection
                    Actions.Add(GetNextActionID, "Add Center", Entities.Modules.Actions.ModuleActionType.AddContent, "", "", EditUrl("CenterID", "-1"), False, Security.SecurityAccessLevel.Edit, CanAdd(), False)
                    Return Actions
                End Get
            End Property
    
    #End Region
    
    #Region " Web Form Designer Generated Code "
    
            'This call is required by the Web Form Designer.
             Private Sub InitializeComponent()
    
            End Sub
    
            Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
                'CODEGEN: This method call is required by the Web Form Designer
                'Do not modify it using the code editor.
                InitializeComponent()
    
            End Sub
    
    #End Region
    
            Private Sub btnAddCenter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddCenter.Click
                Response.Redirect(EditUrl("CenterID", "-1"), True)
            End Sub
        End Class
    
    End Namespace
    

    And finally, here's part of the codebehind for the main (parent) view control:
    Imports DotNetNuke
    Imports System.Web.UI.WebControls
    Imports DotNetNuke.Common
    Imports DotNetNuke.Modules.WESNet.Centers.Common
    Imports DotNetNuke.Security
    Imports System.Text
    
    Namespace DotNetNuke.Modules.WESNet.Centers
    
        Public MustInherit Class Centers
            Inherits Centers_Base
    
    #Region "Controls"
            Protected WithEvents lblStatus As System.Web.UI.WebControls.Label
            Protected WithEvents phView As System.Web.UI.WebControls.PlaceHolder
            Protected WithEvents rptGroup As System.Web.UI.WebControls.Repeater
            Protected WithEvents cblAccess As System.Web.UI.WebControls.CheckBoxList
            Protected WithEvents tbSearch As System.Web.UI.WebControls.TextBox
            Protected WithEvents ctlPagingControl As DotNetNuke.UI.WebControls.PagingControl
            Protected WithEvents ddlPageSize As System.Web.UI.WebControls.DropDownList
            Protected WithEvents rblSortBy As System.Web.UI.WebControls.RadioButtonList
            Protected WithEvents tblFiltering As System.Web.UI.HtmlControls.HtmlTable
            Protected WithEvents tblPaging As System.Web.UI.HtmlControls.HtmlTable
            Protected WithEvents btnSearch As System.Web.UI.WebControls.Button
    #End Region
    
    #Region "Private Variables"
            Private _QueryHashtable As New Hashtable(5)
            Protected WithEvents _ViewControl As Centers_Base
    
            Private _SortBy As String
            Private _Group As String
            Private _Filter As String
            Private _PageSize As Integer
            Private _CurrentPage As Integer
    
    
            Private _TotalRecords As Integer
    #End Region
    
    #Region "Private Properties"
    
            Private Property View() As String
                Get
                    If Viewstate("view") Is Nothing Then
                        If Not CType(Settings("view"), String) Is Nothing Then
                            Return CType(Settings("view"), String)
                        Else
                            Return "STD"
                        End If
                    End If
                End Get
                Set(ByVal Value As String)
                    Viewstate("view") = Value
                End Set
            End Property
    
            Private ReadOnly Property ViewControl() As Centers_Base
                Get
                    Return _ViewControl
                End Get
            End Property
    
    #End Region
    
    #Region "Public Properties"
    
    #End Region
    
    #Region "Public Methods"
    
            Public Sub ShowStatus(ByVal Message As String)
                lblStatus.Text = Message
            End Sub
    
            Public Sub ShowError(ByVal Message As String)
                lblStatus.Text = "
    " & Message & "
    " End Sub Public Sub ClearStatus() lblStatus.Text = String.Empty End Sub Public Overrides Sub BindView() If rblSortBy.Visible Then SortBy = rblSortBy.SelectedValue Else If Not Request.QueryString("sortby") Is Nothing AndAlso Request.QueryString("sortby").Length > 0 Then SortBy = Request.QueryString("sortby") Else SortBy = CType(Settings("sortby"), String) End If End If If ddlPageSize.Visible Then PageSize = CInt(ddlPageSize.SelectedValue) Else If Not Request.QueryString("pagesize") Is Nothing AndAlso Request.QueryString("pagesize").Length > 0 Then PageSize = CInt(Request.QueryString("pagesize")) Else PageSize = CInt(CType(Settings("pagesize"), String)) End If End If If ctlPagingControl.Visible Then CurrentPage = ctlPagingControl.CurrentPage Else If Not Request.QueryString("currentpage") Is Nothing AndAlso Request.QueryString("currentpage").Length > 0 Then CurrentPage = CInt(Request.QueryString("currentpage")) End If End If _ViewControl.DataSource = GetData() _ViewControl.BindView() End Sub #End Region #Region "Event Handlers" Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Try If Not IsPostBack Then If Not Request.QueryString("view") Is Nothing AndAlso Request.QueryString("view").Length > 0 Then View = Request.QueryString("view") End If Select Case View Case "STD" _ViewControl = CType(LoadControl(ModulePath & "Centers_Standard.ascx"), Centers_Standard) Case "RPT" _ViewControl = CType(LoadControl(ModulePath & "Centers_Report.ascx"), Centers_Report) Case "WEB" _ViewControl = CType(LoadControl(ModulePath & "Centers_Websites.ascx"), Centers_Websites) Case "EML" _ViewControl = CType(LoadControl(ModulePath & "Centers_EMails.ascx"), Centers_EMails) End Select If Not _ViewControl Is Nothing Then _ViewControl.ModuleConfiguration = Me.ModuleConfiguration AddHandler _ViewControl.RefreshRequested, AddressOf ViewControl_RefreshRequested phView.Controls.Add(_ViewControl) BindView() End If Catch exc As Exception 'Module failed to load ProcessModuleLoadException(Me, exc) End Try End Sub Private Function GetData() As ArrayList End Function #End Region #Region " Web Form Designer Generated Code " 'This call is required by the Web Form Designer. Private Sub InitializeComponent() End Sub Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init 'CODEGEN: This method call is required by the Web Form Designer 'Do not modify it using the code editor. InitializeComponent() End Sub #End Region #Region "Events" Private Sub rblSortBy_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rblSortBy.SelectedIndexChanged ctlPagingControl.CurrentPage = 1 tbSearch.Text = String.Empty BindView() End Sub Private Sub rptGroup_ItemCommand(ByVal source As System.Object, ByVal e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles rptGroup.ItemCommand Group = Convert.ToString(e.CommandArgument) ctlPagingControl.CurrentPage = 1 tbSearch.Text = String.Empty BindView() End Sub Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click Group = tbSearch.Text ctlPagingControl.CurrentPage = 1 BindView() End Sub Private Sub ddlPageSize_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ddlPageSize.SelectedIndexChanged ctlPagingControl.CurrentPage = 1 BindView() End Sub Private Sub ViewControl_RefreshRequested(ByVal sender As System.Object, ByVal e As System.EventArgs) ctlPagingControl.CurrentPage = 1 BindView() End Sub #End Region End Class End Namespace

    Note that I have cut a lot out of the last class that does not directly effect the child/parent view control relationship - so don't expect the class to compile as is.
    Bill, WESNet Designs
  • Re: Please help: Multi-Interface Module

    11-21-2005, 6:57 PM
    • Member
      390 point Member
    • workcontrol
    • Member since 11-15-2005, 7:19 AM
    • Posts 78
Page 1 of 1 (5 items)