views:

236

answers:

1

Hello

I have an ASP:Repeater Which I would like to display a list of check boxes in. These check boxes are related to a list of user preferences and the users resulting answer. See Code Bellow.

I would like to add do one of the following if possible

Option 1: It would be great if I could use the Event in the Repeater:OnItemCommand(...) to fire if any of the items change. It would seem to me that this event will only fire if there is a Button | LinkButton | ImageButton item in the list. IE it will not fire if I put in a check box with AutopostBack="True"

Option 2: Is there a way I could attach a method to an Event of CheckBox:CheckChanged I would need to pass this method a parameter saying which question/answer combo to change.

Option 3: Its your answer if you know an easier way that would be awesome.

The Code:

<asp:Repeater ID="RPTprefs" runat="server" DataSourceID="getAnswers"    OnItemCommand="RPTprefs_ItemCommand">
      <ItemTemplate>
         <li><asp:CheckBox ID='questionID' runat="server" 
        Checked='<%# Eval("pr.up_is_selected") %>' 
        Text='<%# Eval("prp.prefs_question") %>' 
        AutoPostBack="true"
        OnCheckedChanged="CheckChanged"  /></li>
                </ItemTemplate>
               </asp:Repeater>

Thanks in advance

+2  A: 

Here is what I came up with, which is basically your option #2. In the ItemTemplate of the repeater, I use a Literal control (Visible set to false) which has the argument you wish to pass to the CheckedChanged function. The reason for using a control is because the control will retain its value in the ViewState after a post back, whereas the original data source for the Repeater will be lost.

In the OnItemCreated function, I bind the CheckChanged function for all of the check boxes to pass in the right argument. Here's my complete example. In this case, I want to pass the Id property of my data to the CheckChanged function.

Markup:

<asp:Repeater ID="Repeater1" runat="server" OnItemCreated="ItemCreated">
       <ItemTemplate>
           <asp:Literal ID="litArg" runat="server" Visible="false" Text='<%# Eval("Id") %>'>
           </asp:Literal><%# Eval("Name") %>
           <asp:CheckBox ID="chkCool" runat="server" AutoPostBack="true" Checked='<%# Eval("IsCool") %>' /><br />
       </ItemTemplate>
</asp:Repeater>

Code behind:

public class SomeClass
{
    public SomeClass(bool c, string n, int id)
    {
        IsCool = c;
        Name = n;
        Id = id;
    }
    public bool IsCool { get; set; }
    public string Name { get; set; }
    public int Id { get; set; }
}
.
.
.

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        List<SomeClass> people = new List<SomeClass>();

        people.Add(new SomeClass(true, "Will", 666));
        people.Add(new SomeClass(true, "Dan", 2));
        people.Add(new SomeClass(true, "Lea", 4));
        people.Add(new SomeClass(false, "Someone", 123));

        Repeater1.DataSource = people;
        Repeater1.DataBind();
    }
}

private void CheckChanged(int id)
{
    Response.Write("CheckChanged called for item #" + id.ToString());
}

protected void ItemCreated(object sender, RepeaterItemEventArgs e)
{
    //this needs to be set again on post back
    CheckBox chk = (CheckBox)e.Item.FindControl("chkCool");
    Literal arg = (Literal)e.Item.FindControl("litArg");

    Action<object, EventArgs> handler = (s, args) => CheckChanged(Convert.ToInt32(arg.Text));
    chk.CheckedChanged += new EventHandler(handler);
}

Hope that helps.

wsanville
Thank you, Thank you. One thousand times thank you. I have been trying to solve this for 2 days. You really put in a bit of effort for this answer I wish i could up vote more than once. ;)
Kieran
No problem :). I gotta say, sometimes the asp.net controls are just not easy to work with.
wsanville