1

I am using nested repeater and child repeater has a user control in it.

<asp:repeater>
<asp:repeater>
    <uc:userControl />
</asp:repeater>
</asp:repeater>

UserControl saves the information in database and raise the itemsaved event passing success message as event args.

I do have public event in usercontrol that will be raised but there is no way I can bind that event in the main page. (it would be really good if I can do that).

But I found another way to handle it in parent repeater's itemcommand. First it will fire usercontrol's button event and then repeater's itemcommand. I can recognize that usercontrol's event in itemcommand but how do I pass whether the information saved successfully or not? Is there any way I can pass true/false(successful save or not) from usercontrol's button event to itemcommand event?

user655810
  • 21
  • 1
  • 2

1 Answers1

3

You can handle your UserControl's event in the page. You have to add the handler in ItemCreated-event of your inner repeater.

Here is a working example(VB.Net):

Main-Page codebehind:

Public Class RepeaterTest
    Inherits System.Web.UI.Page

    Sub Page_Load(ByVal Sender As Object, ByVal e As EventArgs) Handles Me.Load
        If Not IsPostBack Then
            Dim comps As New List(Of Company)
            comps.Add(New Company("Microsoft"))
            comps.Add(New Company("Intel"))
            comps.Add(New Company("Dell"))
            Repeater1.DataSource = comps
            Repeater1.DataBind()
        End If
    End Sub

    Protected Sub Repeater1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)
        Select Case e.Item.ItemType
            Case ListItemType.Item, ListItemType.AlternatingItem
                Dim company As Company = DirectCast(e.Item.DataItem, Company)
                Dim repeater2 As Repeater = DirectCast(e.Item.FindControl("Repeater2"), Repeater)
                Dim deps As New List(Of Department)
                deps.Add(New Department("purchasing", company))
                deps.Add(New Department("management", company))
                deps.Add(New Department("marketing", company))
                deps.Add(New Department("logistics ", company))
                repeater2.DataSource = deps
                repeater2.DataBind()
        End Select
    End Sub

    Protected Sub Repeater2_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)
        Select e.Item.ItemType
            Case ListItemType.Item, ListItemType.AlternatingItem
                Dim uc_department As UC_Department = DirectCast(e.Item.FindControl("UC_Department1"), UC_Department)
                '*** Here is all the "magic" ***'
                AddHandler uc_department.NameChanged, AddressOf DepartmentSaved
        End Select
    End Sub

    Protected Sub Repeater2_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)
        Select Case e.Item.ItemType
            Case ListItemType.Item, ListItemType.AlternatingItem
                Dim department As Department = DirectCast(e.Item.DataItem, Department)
                Dim uc_department As UC_Department = DirectCast(e.Item.FindControl("UC_Department1"), UC_Department)
                uc_department.Department  = department
        End Select
    End Sub

    Private Sub DepartmentSaved(ByVal uc_Department As UC_Department)
        ' do something f.e. save to database '
    End Sub
End Class

<Serializable()>
Public Class Company
    Public Sub New(ByVal name As String)
        Me.Name = name
    End Sub
    Public Property Name As String
    Public Overrides Function ToString() As String
        Return Me.Name
    End Function
End Class

<Serializable()>
Public Class Department
    Public Sub New(ByVal name As String, ByVal company As Company)
        Me.Name = name
        Me.Company = company
    End Sub

    Public Property Name As String
    Public Property Company As Company

    Public Overrides Function ToString() As String
        Return Me.Name
    End Function
End Class

aspx:

   <asp:Repeater id="Repeater1" OnItemDataBound="Repeater1_ItemDataBound" runat="server">
         <HeaderTemplate>
            <table border="1">
               <tr>
                  <td><b>Company</b></td>
                  <td><b>Departments</b></td>
               </tr>
         </HeaderTemplate>

         <ItemTemplate>
            <tr>
               <td> 
                  <%# DataBinder.Eval(Container.DataItem, "Name")%> 
               </td>
               <td> 
                   <asp:Repeater ID="Repeater2" OnItemCreated="Repeater2_ItemCreated" OnItemDataBound="Repeater2_ItemDataBound" runat="server">
                         <HeaderTemplate>
                            <table border="1">
                         </HeaderTemplate>

                         <ItemTemplate>
                            <tr>
                               <td> 
                                  <uc1:UC_Department ID="UC_Department1" runat="server" />
                               </td>
                            </tr>
                         </ItemTemplate>

                         <FooterTemplate>
                            </table>
                         </FooterTemplate>
                   </asp:Repeater>
               </td>
            </tr>
         </ItemTemplate>

         <FooterTemplate>
            </table>
         </FooterTemplate>

      </asp:Repeater>

The usercontrol's codebehind:

Public Class UC_Department
    Inherits System.Web.UI.UserControl

    Public Event NameChanged(ByVal ucDepartment As UC_Department)

    Public Property Department As Department
        Get
            If ViewState("Company") Is Nothing Then Return Nothing
            Return New Department(Me.TxtName.Text, DirectCast(ViewState("Company"), Company))
        End Get
        Set(ByVal value As Department)
            Me.TxtName.Text = value.Name
            ViewState("Company") = value.Company
        End Set
    End Property

    Private Sub BtnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles BtnSave.Click
        RaiseEvent NameChanged(Me)
    End Sub
End Class

and its ascx:

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="UC_Department.ascx.vb" Inherits="DemoProject.UC_Department" %>
<asp:TextBox ID="TxtName" runat="server"></asp:TextBox>
<asp:Button ID="BtnSave" runat="server" Text="Save" />
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • I already tried that but it wasn't triggering method that subscribed to event.(in your case DepartmentSaved). I think AddHandler inside nested repeater doesn't work. – user655810 Mar 18 '11 at 16:03
  • 1
    @user655810: but this is exactly your case. A Usercontrol in a nested repeater and believe me, it works ;) Where did you add the handler? You must add it in ItemCreated of the nested repeater like in my example and not in ItemDataBound(ItemCreated is called on every postback as against ItemDataBound). – Tim Schmelter Mar 18 '11 at 16:23
  • Awesome spent huge amount of time trying to figure this out. Thanks!! +1 – Brad8118 Apr 06 '11 at 21:33