views:

593

answers:

2

This is the repeater:

<asp:Repeater ID="rptrReports" runat="server">
            <ItemTemplate>
                <div style="margin: 2">
                    <asp:Label ID="lblAccount" runat="server" Text='<%#Eval("Account").FullName%>'  />&nbsp;
                    <asp:TextBox ID="txtDescription" runat="server" MaxLength="256" Text='<%#Eval("Description")%>'
                        ReadOnly="<%# Not Account.IsAdmin %>" BackColor="<%# If(Account.IsAdmin,Color.White, Color.Transparent)  %>"
                        BorderStyle="<%# If(admin, BorderStyle.NotSet, BorderStyle.None) %>" 
                        />&nbsp;
                    <asp:TextBox ID="txtNote" runat="server" MaxLength="1024" Text='<%#Eval("Note")%>'
                        ReadOnly="<%# Not Account.IsAdmin %>" BackColor="<%# If(Account.IsAdmin,Color.White, Color.Transparent)  %>"
                        BorderStyle="<%# If(admin, BorderStyle.NotSet, BorderStyle.None) %>" />&nbsp;
                    <!-- Here I have many more controls which I want to apply same rules !-->
                </div>
     </ItemTemplate>
</asp:Repeater>

I want to set these controls of the itemtemplate in code dynamically so the asp.net code shouldn't look so ugly:

Private Sub HandleTextBoxes()
    Dim admin = Account.IsAdmin
    For Each tb As TextBox In _
                        From c In rptrReports.Controls  _
                        Where TypeOf c Is TextBox 'ItemTemplate doesn't expose the properties :(
        With tb
            .ReadOnly = Not admin
            .BackColor = If(admin, Color.White, Color.Transparent)
            .BorderStyle = If(admin, BorderStyle.NotSet, BorderStyle.None)
        End With
    Next
End Sub

In the other hand, I don't want to set it or each bound ItemTemplate separately, I want to set it thru to parent control (the repeater) itself.

Answers in C# will be welcomed too!

+2  A: 

The only way I can think of is to hook up to the ItemDataBound of the Repeater

protected void rptrReports_ItemDataBound(object sender, RepeaterItemEventArgs e) {
  var admin = Account.IsAdmin;
  var txtDescription = (TextBox) e.Item.FindControl("txtDescription");
  var txtNote = (TextBox) e.Item.FindControl("txtNote");
  txtDescription.ReadOnly = admin;
  txtDescription.BackColor = admin ? Color.White : Color.Transparent;
  //...
}

If you want to select all the TextBoxes, you can do:

var textBoxes = e.Item.Controls.OfType<TextBox>();
foreach (TextBox textBox in textBoxes) {
  // do stuff with the textBox...
}

If you don't want to use the ItemDataBound event, you can put this code in the Page_PreRender method:

protected void Page_PreRender(object sender, EventArgs e) {
  for (int i = 0 ; i < rInterlocuteurs.Items.Count ; i++) {
    var textBoxes = rInterlocuteurs.Items[i].Controls.OfType<TextBox>();
    foreach (TextBox textBox in textBoxes) {
      // do stuff with the textBox...
    }
  }
}
Julien Poulin
Is there any way to find all the controls in the repeater?Control[] controls = rpeater.FindAllControls();
Shimmy
Yes, you can access all the controls by using the e.Item.Controls collection
Julien Poulin
no, I don't want to access eI want to set it up before the item is even bound.
Shimmy
Then why use a repeater ?
Julien Poulin
I updated my question.
Shimmy
You can't access the controls inside the repeater's ItemTemplate because in the end, the Repeater is just a collection of RepeaterItem and affecting the ItemTemplte won't have any effect on the collection itself...
Julien Poulin
+1  A: 

VB:

Private Shared Sub HandleTextBoxes(ByVal controls As ControlCollection)
    Dim admin = Account.IsAdmin

    If controls.Count > 0 Then
        For Each Control In controls
            HandleTextBoxes(Control.Controls)
        Next
    End If

    For Each tb As TextBox In _
                        From c In controls _
                        Where TypeOf c Is TextBox
        With tb
            .ReadOnly = Not admin
            .BackColor = If(admin, Color.White, Color.Transparent)
            .BorderStyle = If(admin, BorderStyle.NotSet, BorderStyle.None)
        End With
    Next
End Sub

C#:

private static void HandleTextBoxes(ControlCollection controls)
{
    var admin = Account.IsAdmin;

    if (controls.Count > 0) 
        foreach (var Control in controls)
            HandleTextBoxes(Control.Controls);        

    foreach (TextBox tb in ) {        
        tb.ReadOnly = !admin;
        tb.BackColor = admin ? Color.White : Color.Transparent;
        tb.BorderStyle = admin ? BorderStyle.NotSet : BorderStyle.None;
    }
}
Shimmy