catching SelectedIndexChanged of a dropdown list inside a repeater - c#

I am trying to catch the SelectedIndexChanged of a DropDownList inside a Repeater. I have searched the internet but could not find a specific answer any help would be great. This is my code.
page.aspx
<asp:Repeater id="CategoryMyC" OnItemCommand="SomeEvent_ItemCommand" runat="server">
<HeaderTemplate>
<table><tr>
</HeaderTemplate>
<ItemTemplate>
<td>
<table width="100%">
<tr>
<th>Edit Carousel Item</th>
</tr>
<tr>
<td>Choose a product:</td>
</tr>
<tr>
<td>
<asp:DropDownList ID="ddlMcProducts"
DataTextField="Name"
onselectedindexchanged="MyListIndexChanged"
AutoPostBack="true"
DataSource='<%# ProductsManager.GetMerchantProductRepeater(Convert.ToInt32(Eval("MID"))) %>'
runat="server">
</asp:DropDownList>
</td>
</tr>
</table>
</td>
</ItemTemplate>
<FooterTemplate>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
page.aspx.cs
In the Page_Load:
List<CarouselProducts> CP = CarouselProductsManager.GetCarouselItems(Convert.ToInt32(Session["Mid"]));
CategoryMyC.DataSource = CP;
CategoryMyC.ItemDataBound += new RepeaterItemEventHandler(RepeaterItemDataBound);
CategoryMyC.DataBind();
Other events:
protected void ddlMcProducts_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList d = (DropDownList)sender;
// Use d here
System.Windows.Forms.MessageBox.Show("I am changing");
}
protected virtual void PageInit(object sender, EventArgs e)
{
//get all the Carousel item of the merchant
List<CarouselProducts> CP = CarouselProductsManager.GetCarouselItems(Convert.ToInt32(Session["Mid"]));
//MerchantCategoryMyCarousel.DataSource = CP;
//MerchantCategoryMyCarousel.DataBind();
MerchantCategoryMyCarousel.DataSource = CP;
MerchantCategoryMyCarousel.ItemDataBound += new RepeaterItemEventHandler(RepeaterItemDataBound);
MerchantCategoryMyCarousel.DataBind();
}
protected virtual void RepeaterItemDataBound(object sender, RepeaterItemEventArgs e)
{
DropDownList theDropDown = sender as DropDownList;
if (e.Item.ItemType == ListItemType.EditItem)
{
DropDownList MyList = (DropDownList)e.Item.FindControl("ddlMcProducts");
if (MyList == null)
{
System.Windows.Forms.MessageBox.Show("Did not find the controle");
}
else
MyList.SelectedIndexChanged += new EventHandler(MyListIndexChanged);
}
}
protected virtual void MyListIndexChanged(object sender, EventArgs e)
{
System.Windows.Forms.MessageBox.Show("I am changing");
}
protected void SomeEvent_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandSource.GetType() == typeof(DropDownList))
{
DropDownList ddlSomething = (DropDownList)e.Item.FindControl("ddlSomething");
System.Windows.Forms.MessageBox.Show("I am changing");
//Now you can access your list that fired the event
//SomeStaticClass.Update(ddlSomething.SelectedIndex);
}
}
I need to catch the SelectedIndexChanged of the populated DropDownList for each one generated.

You've got quite a mismatch of code going on here - using System.Windows.Forms in an ASP.NET application is just one of the issues. You appear to be assigning event handlers in the code-behind and in the markup (nothing necessarily bad about that, but there's seems to be no rhyme or reason to how you're doing it).
You're Repeater's ItemCommand event is bound to a method that is looking for a DropDownList that has a different ID than the one in your markup.
If you're using the System.Windows.Forms.MessageBox to debug (ala old school JavaScript and other language "debugging" methods), save yourself a world-class headache (not to mention a lot of unnecessary code cleanup when you're done with development) and step through your code in the debugger.
I'm not sure how the page will render, but I don't think you're using the HeaderTemplate and FooterTemplate quite the way they're intended.
All that said, try something like this:
Markup (ASPX page):
<asp:Repeater id="CategoryMyC" OnItemCommand="CategoryMvC_ItemCommand" OnItemDataBound="CategoryMvC_ItemDataBound" runat="server">
<HeaderTemplate>
<table>
<tr>
<th>Edit Carousel Item</th>
</tr>
</table>
</HeaderTemplate>
<ItemTemplate>
<table width="100%">
<tr>
<td>Choose a product:</td>
</tr>
<tr>
<td>
<asp:DropDownList ID="ddlMcProducts"
DataTextField="Name"
OnSelectedIndexChanged="ddlMcProducts_SelectedIndexChanged"
AutoPostBack="true"
DataSource='<%# ProductsManager.GetMerchantProductRepeater(Convert.ToInt32(Eval("MID"))) %>'
runat="server">
</asp:DropDownList>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
Code Behind (APSX.CS)
protected void Page_Load(object sender, EventArgs e)
{
List<CarouselProducts> CP = CarouselProductsManager.GetCarouselItems(Convert.ToInt32(Session["Mid"]));
CategoryMyC.DataSource = CP;
//This can be assigned in the markup
//CategoryMyC.ItemDataBound += new RepeaterItemEventHandler(RepeaterItemDataBound);
CategoryMyC.DataBind();
}
protected void ddlMcProducts_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList d = (DropDownList)sender;
// Use d here
}
protected void CategoryMyC_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
DropDownList theDropDown = sender as DropDownList;
if (e.Item.ItemType == ListItemType.EditItem)
{
DropDownList MyList = (DropDownList)e.Item.FindControl("ddlMcProducts");
// This section is not needed for what you are doing with it:
// If the control is null, handle it as an error
// There's no need to give it an event handler if it does exist, because
// you already did so in the markup
//if (MyList == null)
//{
//System.Windows.Forms.MessageBox.Show("Did not find the controle");
//}
//else
//MyList.SelectedIndexChanged += new EventHandler(MyListIndexChanged);
//}
}
}
protected void CategoryMyC_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandSource.GetType() == typeof(DropDownList))
{
// Note the correct control name is being passed to FindControl
DropDownList ddlSomething = (DropDownList)e.Item.FindControl("ddlMcProducts");
//System.Windows.Forms.MessageBox.Show("I am changing");
//Now you can access your list that fired the event
//SomeStaticClass.Update(ddlMcProducts.SelectedIndex);
}
There may be more issues at hand as well - but this will hopefully streamline it enough for you to make some progress.

protected void drpOrganization_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddl = (DropDownList)sender;
RepeaterItem item = (RepeaterItem)ddl.NamingContainer;
if (item != null)
{
CheckBoxList list = (CheckBoxList)item.FindControl("chkSite");
if (list != null)
{
}
}
}

Related

How to get text in textbox inside an asp.net repeater on postback?

I bind data to the repeater on Page Init:
protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack)
{
repeaterInfo.DataSource = //getDataSource;
repeaterInfo.DataBind();
}
}
Here's the markup page
<table class="beautifulTable">
<asp:Repeater runat="server" ID="repeaterInfo" OnItemCreated="repeaterInfo_ItemCreated">
<ItemTemplate>
<tr>
<td style="display: none">
<asp:TextBox runat="server" Width="90%" ID="txtUserInput"></asp:TextBox>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
Here's the Item created event:
protected void repeaterInfo_ItemCreated(object sender, RepeaterItemEventArgs e)
{
if (e.Item.DataItem == null)
return;
TextBox txtUserInput= e.Item.FindControl("txtUserInput") as TextBox;
txtUserInput.Text = "0.0"; //Default value
}
And I would like to save the user input to database when the user clicks the submit button:
protected void btnSubmit_Click(object sender, EventArgs e)
{
List<repeaterType> source = repeaterInfo.DataSource as List<repeaterType>;
for (int z = 0; z < source.Count; z++)
{
TextBox txtUserInput = repeaterInfo.Items[z].FindControl("txtUserInput") as TextBox;
//Get text and do logic here
}
//Saves data to database
}
And here's the problem:
The repeaterInfo datasource is null on postback
If I remove the !IsPostBack, the txtUserInput text will be resetted (0.0)
I've enabled the viewstate on the markup page using EnableViewState="true"
How I can get the text in txtUserInput?
The repeater's datasource is not persisted in cross postbacks. If you just want to iterate and get the user inputs, you can just iterate through the items and get those like this:
foreach (RepeaterItem item in repeaterInfo.Items)
{
if(item.ItemType == ListItemType.Item)
{
var txtUserInput = item.FindControl("txtUserInput") as TextBox;
}
}
If you want the datasource to be persisted (may be to avoid database calls), use the ViewState (watch out for large number of rows):
ViewState["myDataSource"] = myDatasource;

C# Get first repeater item column value to use on HeaderTemplate

I'm trying to get a column value of the first element on a repeater, and use it on the repeater's HeaderTemplate. After searching and trying many ways of achieving this through intellisense, I gave up and decided to post this question here.
My code is as follows:
Frontend
<asp:Repeater ID="states" runat="server">
<HeaderTemplate>
<h1>Stage: <asp:Literal ID="stageName" runat="server"></asp:Literal></h1>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><%# DataBinder.Eval(Container.DataItem, "StateName") %></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
Backend
protected void BindStageStates()
{
List<StagesStatesModel> statesList = App.Services.Stages.StagesService.GetStatesByStage(Page.DefaultApp, 1, Page.DefaultCultureId).Where(p => p.StateActive == true).ToList();
states.ItemDataBound += new RepeaterItemEventHandler(rptStagesStatesDataBound);
states.DataSource = statesList;
states.DataBind();
}
void rptStagesStatesDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header)
{
Literal stageName = (Literal)e.Item.FindControl("stageName");
stageName.Text = // Something to go here..
}
}
Thanks in advance!
Try OnItemCreated
protected void Repeater_OnItemCreated(Object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Footer)
{
e.Item.FindControl(ctrl);
}
if (e.Item.ItemType == ListItemType.Header)
{
e.Item.FindControl(ctrl);
}
}
By:
How to find controls in a repeater header or footer

SelectedIndexChanged

Problem:
SelectedIndexchanged does not fire. I tried investigating with a breakpoint but it does not even get to the event.
I made the event by double clicking on the combobox. But it did not help.
Please advice.
Here is the code:
protected void nav_dd_parent_edit_SelectedIndexChanged(object sender, EventArgs e)
{
}
<td width="55%" class="style1" height="20px">
<asp:DropDownList ID="nav_dd_parent_edit" runat="server"
DataSourceID="sp_GetNavParents_Edit" DataTextField="Name"
DataValueField="NavItemId" Height="24px" ReadOnly="FALSE" Width="375px"
onselectedindexchanged="nav_dd_parent_edit_SelectedIndexChanged">
</asp:DropDownList>
</td>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//Page.MaintainScrollPositionOnPostBack = true;
//SiteMaster.g_solution = "Couche-Tard - QV";
//SiteMaster.g_solution_id = 27;
nav_dd_parent.DataBind();
if (SiteMaster.g_solution != null && SiteMaster.g_solution != "")
{
nav_literal.Text = "Solution: " + SiteMaster.g_solution;
nav_hidden_SoltnId.Value = SiteMaster.g_solution_id.ToString();
}
else
{
nav_literal.Text = "Please select a solution first from the 'Solution Template' Tab.";
panel_top.Visible = false;
}
}
You're not seeing your breakpoint get hit because the dropdownlist is not posting back when the selection changes.
Set AutoPostBack to true and you should be all set.
I noticed your DropDownList Id is "nav_dd_parent_edit", but your Page_Load is calling the Databind method on "nav_dd_parent" - could that be part of the problem?
Anyway, I did a simplified version of your DropDownList that works fine - perhaps it might help.
<table>
<tr>
<td width="55%" class="style1" height="20px">
<asp:DropDownList
ID="nav_dd_parent"
runat="server"
DataTextField="Name"
DataValueField="NavItemId"
Height="24px"
ReadOnly="FALSE"
Width="375px"
onselectedindexchanged="nav_dd_parent_edit_SelectedIndexChanged"
AutoPostBack="true">
</asp:DropDownList>
</td>
</tr>
</table>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
nav_dd_parent.Items.Add(new ListItem("Item 1", "1"));
nav_dd_parent.Items.Add(new ListItem("Item 2", "2"));
nav_dd_parent.Items.Add(new ListItem("Item 3", "3"));
}
}
protected void nav_dd_parent_edit_SelectedIndexChanged(object sender, EventArgs e)
{
int codeGetsHere = 0;
}
Few notes to keep in mind as below:
a. Set 'AutoPostBack' to true :
<asp:DropDownList ID="nav_dd_parent_edit" runat="server" AutoPostBack="true"
DataSourceID="sp_GetNavParents_Edit" DataTextField="Name"
DataValueField="NavItemId"
onselectedindexchanged="nav_dd_parent_edit_SelectedIndexChanged">
</asp:DropDownList>
b. Always bind on not postback time :
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
nav_dd_parent_edit.DataSource = yourDataSourceName;
nav_dd_parent_edit.DataBind();
}
}

Edit Textbox in Repeater

I have a repeater with a textbox inside. I am trying to edit the information inside the textbox, retrieve the new data, and write to the DB. With my code its giving me the original info that was in the box. Not the new information that I have added. Here is my code
html:
<asp:LinkButton id="saveReviewLinkButton" text="Save" runat="server" onCommand="saveReviewLinkButton_OnCommand" />
<table>
<asp:Repeater id="ReviewRepeater" runat="server" onItemDataBound="ReviewRepeater_ItemDataBound">
<itemtemplate>
<tr >
<td ><asp:TextBox id="titleLabel" runat="server" width="200px" textMode="MultiLine"/></td>
</tr>
</itemtemplate>
</table>
c#:
protected void ReviewRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
{
Review review = (Review)e.Item.DataItem;
TextBox titleLabel = (TextBox)e.Item.FindControl("titleLabel");
titleLabel.Text = review.Title;
}
}
protected void saveReviewLinkButton_OnCommand(object sender, EventArgs e)
{
TextBox titleLabel = new TextBox();
foreach (RepeaterItem dataItem in ReviewRepeater.Items)
{
titleLabel = (TextBox)dataItem.FindControl("titleLabel");
string newInfo = titleLabel.Text;
}
}
Please make sure, you are binding the data to the repeater by checking in page load
if(!IsPostBack)
BindData();

Get selected dropdownlist value inside a repeater control

I have dropdownlist inside of a repeater control that I'm trying to get the value of and I'm getting "Object reference not set to an instance of an object". I am not sure what else to try. Thanks
ASPX CODE:
<asp:Repeater ID="GeneralRepeater" runat="server"
OnItemDataBound="GeneralRepeater_OnItemDataBound"
onitemcommand="GeneralRepeater_ItemCommand">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<tr>
<td class="style2">
</td>
<td class="style2">
<asp:DropDownList ID="GeneralDDL" AppendDataBoundItems="true" DataTextField="DiagnosisCode"
DataValueField="DiagnosisCode" runat="server" AutoPostBack="True" />
</td>
</tr>
</ItemTemplate>
<FooterTemplate></FooterTemplate>
</asp:Repeater>
</asp:Panel>
CODE BEHIND:
protected void GeneralRepeater_OnItemDataBound(object sender,
RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
DropDownList myDDL = (DropDownList)e.Item.FindControl("GeneralDDL");
Diagnosis oDiagnosis = new Diagnosis();
DataView dv = new DataView(oDiagnosis.GetDiagnosis());
myDDL.DataSource = dv;
myDDL.DataTextField = "DiagnosisCode";
myDDL.DataValueField = "DiagnosisCode";
myDDL.DataBind();
}
}
protected void cmdSave_Click(object sender, EventArgs e)
{
string ProductSelected;
string FeatureSelected;
string SectionSelected;
foreach(RepeaterItem dataItem in GeneralRepeater.Items)
{
ProductSelected = ((DropDownList)GeneralRepeater.FindControl("GeneralDDL")).SelectedItem.Text; //error Object reference not set to an instance of an object.
}
}
I having problem on Saving the selected value..
What i find in the code is you are looping through the generalrepeater items. You are accessing the repeater item as dataItem. I tried out this code out here and ideally your code should say
foreach(RepeaterItem dataItem in GeneralRepeater.Items)
{
ProductSelected = ((DropDownList)dataItem.FindControl("GeneralDDL")).SelectedItem.Text; //No error
}
instead of
foreach(RepeaterItem dataItem in GeneralRepeater.Items)
{
ProductSelected = ((DropDownList)GeneralRepeater.FindControl("GeneralDDL")).SelectedItem.Text; //error Object reference not set to an instance of an object.
}

Categories

Resources