views:

1719

answers:

4

Hello,

Maybe this is something very easy to do it but so far it's taking me all day to have something working.

I have a repeater filled with a table. Each row in the repeater has a set of controls. The most important of them is a drop down list with AutoPostback = true.

This ddl has to postback when the user changes the selected index so I can hide/show controls within the ddl.

The problem is that when the user changes the selected index in the ddl, and the control postback, in the server side, I can't get the index of the row that contains the ddl that made postback.

Hope it's clear enough, and that someone can help me out here.

Thanks!

EDIT: Maybe this is something that wasn't clear enough: when I place a control with ID="ddlSomething" inside an ItemTemplate in a repeater, and I have 5 rows in the data source, I will have 5 rows in the repeater with 5 ddl with the same id (on the server side, in the client side will be something like "ctl01$ddlSomething", "ctl02$ddlSomething". My problem is that when the ddl postback, I don't know which of all these 5 (for example) ddl is the one that made the postback, because just looking at Request.Form variables I can see that the control "ddlSomething" made it.

+1  A: 

In a FormView you can do the following maybe it will work in repeaters as well:

In the DDL HTML markup add an attribute for the id to the DDL element:

MyID='<%# Eval("MyID") %>'

In the postback for that element grab that ID:

int intID = Convert.ToInt32((sender as DropDownList).Attributes["MyID"]);
.....

EDIT: If you have a Employees table with employee_name, employee_type and employee_id You might have arepeater that prints out employee name and employee type where employee type is a DLL with Full time, part time, etc. You could add this declaratively to the markup of the DDL:

MyID='<%# Eval("employee_id") %>'

and in the DDL postback:

int employeeID = Convert.ToInt32((sender as DropDownList).Attributes["MyID"]);
Jay
Where is "MyID" defined?
Rex M
MyID is your own custom HTML attribute. It isn't defined anywhere but in your markup. Keep in mind that although this solution would work, you'll get HTML validation errors as a result of the unrecognized attribute. Nothing to fuss over though.
Nathan Taylor
I mean, where is "MyID" in the DataItem defined? MyID has to be a member on the DataItem for Eval() to bind to it.
Rex M
MyID is a column that is returned from your SQL query to the database. I can be any identifier that you user for your data.
Jay
Added some edits for clarity
Jay
+4  A: 

Try:

<asp:DropDownList runat="server" id="myDDL" OnSelectedIndexChanged="myDDL_Changed" />

//fired when the DDL selected index changes
void myDDL_Changed(object sender, EventArgs e)
{
    //sender is the ddl
    DropDownList theDropDown = sender as DropDownList;
    int repeaterItemIndex = ((RepeaterItem)theDropDown.NamingContainer).ItemIndex;
}
Rex M
I don't get it Rex... in which context does this happens? All the ddl has the same id in the server side... how do I do this? the only way I manage to get some info about it is in the Page_load using Request.Form variables.
Sebastian
@Sebastian see my revised answer.
Rex M
Thanks a lot Rex M, this seems to be the best thing to do!
Sebastian
A: 

The repeater itself cannot tell you which control is selected, because the item template you specify could contain any combination of controls and there might not be a way to specify one as 'selected'

You will have to check the inner controls in the repeater list. Since you're creating a table you may be able to check the selected index of the table itself instead of checking the selected index of the repeater.

Otherwise, iterate through the controls and find which one is selected. For example, you may iterate through each row and look for the sending DDL, something like this:

   for( ... )
   {
       if( containingElement.Controls.Find(sender.ID) )
      { 
         // You found it!
      }
      // otherwise keep looking...
   }
TJB
+1  A: 

I may or may not be off the mark here Sebastian, but I believe you're trying to bubble an event.

For example, from your explanation I'm under the impression you're doing something such as:

<asp:Repeater id="myRepeater" runat="server">
    <ItemTemplate>
        <asp:DropDownList ID="ddlSomething" AutoPostBack="true" runat="server"></asp:DropDownList>
    </ItemTemplate>
</asp:Repeater>

To catch an event from within the repeater, you can use the attribute "OnItemCommand", ie:

<asp:Repeater id="myRepeater" OnItemCommand="SomeEvent_ItemCommand" runat="server">
        <ItemTemplate>
            <asp:DropDownList ID="ddlSomething" AutoPostBack="true" runat="server"></asp:DropDownList>
        </ItemTemplate>
    </asp:Repeater>

In your code behind, you are now able to do the following:

protected void SomeEvent_ItemCommand(object sender, RepeaterCommandEventArgs e)
        {
            if (e.CommandSource.GetType() == typeof(DropDownList))
            {
                DropDownList ddlSomething = (DropDownList)e.Item.FindControl("ddlSomething");

                //Now you can access your list that fired the event
                SomeStaticClass.Update(ddlSomething.SelectedIndex);
            }
        }

I hope I haven't gone down the wrong road here, but I think that's something of what you're shooting for.

EDIT:

To add a small comment here, "e.Item" above is the row that has your event has been fired from. So you have full access to other controls in that row, not just your dropdownlist.

Alexis Abril
I think this is a good answer Alexis, thanks. I'll try it later, but first this needs to be shipped! :p
Sebastian