How to access Parent repeater id from code behind - c#

I have a nested repeater on my page like:
Aspx page:
<asp:Repeater ID="parentRepeater" runat="server">
<ItemTemplate>
<br />
<b><%# DataBinder.Eval(Container.DataItem,"question") %></b><br>
<!-- start child repeater -->
<asp:Repeater ID="childRepeater" DataSource='<%# ((DataRowView)Container.DataItem).Row.GetChildRows("relation") %>'
runat="server">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" OnCommand="LinkButton1_Command" CommandName="MyUpdate" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "[\"AnsId\"]")%>'><%# DataBinder.Eval(Container.DataItem, "[\"Ans\"]")%></asp:LinkButton>
<br>
</ItemTemplate>
</asp:Repeater>
<!-- end child repeater -->
</ItemTemplate>
</asp:Repeater>
Code behind:
SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["star_report_con"].ConnectionString);
SqlDataAdapter cmd1 = new SqlDataAdapter("select questionId, question from questions", cnn);
//Create and fill the DataSet.
DataSet ds = new DataSet();
cmd1.Fill(ds, "questions");
//Create a second DataAdapter for the Titles table.
SqlDataAdapter cmd2 = new SqlDataAdapter("SELECT AnsId, Ans, questionId FROM answers", cnn);
cmd2.Fill(ds, "answers");
//Create the relation bewtween the Authors and Titles tables.
ds.Relations.Add("relation",
ds.Tables["questions"].Columns["questionId"],
ds.Tables["answers"].Columns["questionId"]);
//Bind the Authors table to the parent Repeater control, and call DataBind.
parentRepeater.DataSource = ds.Tables["questions"];
Page.DataBind();
//Close the connection.
cnn.Close();
protected void LinkButton1_Command(object sender, CommandEventArgs e)
{
if (e.CommandName == "MyUpdate")
{
//e.CommandArgument --> contain the Ansid value
//I want to also find which questions ans is clicked i.e the questionId
}
}
In my child repeater I have a linkbutton on click of which i need to do some computaion for which I need to know which questions answers wa being clicked. i.e in my LinkButton1_Command I want to fetch the AnsId along with QuestionId.
How will I get parent repeaters Id in button click event?

Try this ,
<%# ((RepeaterItem)Container.Parent.Parent).DataItem %>
If this does not work then try
<%# DataBinder.Eval(Container.Parent.Parent, "DataItem.YourProperty")%>
if you're in code-behind in the ItemDataBound method:
((Repeater)e.Item.NamingContainer.NamingContainer).DataItem

Related

LinkButton OnClick within a Nested Repeater

I am having trouble with a LinkButton firing the OnClick event where the LinkButton is in a nested repeater.
Here is my HTML Markup
<asp:Repeater ID="RepeaterGenres" runat="server" OnItemDataBound="LoadTitles">
<ItemTemplate>
<asp:HiddenField ID="hdnGenre" runat="server" Value='<%# DataBinder.Eval(Container.DataItem, "GenreID") %>' />
<%# DataBinder.Eval(Container.DataItem, "MovieGenre") %>
<asp:Repeater ID="RepeaterMovies" runat="server">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "MovieName") %>
<asp:LinkButton ID="lbMovieInfo" runat="server" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "MovieID") %>' OnClick="LoadMovieTitle">
Access Info
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Here is my method to load the Genres. (have removed some of the declarations to simplify).
string sqlString = "SELECT * FROM Movies_Genres";
sqlCmd = new SqlCommand(sqlString, myConnection);
sqlReader = sqlCmd.ExecuteReader();
if (sqlReader.HasRows)
{
RepeaterGenres.DataSource = sqlReader;
RepeaterGenres.DataBind();
}
Here is my method to load the Movie Titles within each Genre.
protected void LoadTitles(object sender, RepeaterItemEventArgs args)
{
if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem)
{
// Genre from HiddenField
HiddenField GenreID = (HiddenField)args.Item.FindControl("hdnGenre");
// Repeater
Repeater childRepeater = (Repeater)args.Item.FindControl("RepeaterMovies");
string sqlString = "SELECT * FROM Movies_Titles " +
"WHERE Genre = #Genre";
sqlCmd = new SqlCommand(sqlString, myConnection);
sqlCmd.Parameters.AddWithValue("#Genre", GenreID.Value);
sqlReader = sqlCmd.ExecuteReader();
if (sqlReader.HasRows)
{
childRepeater.DataSource = sqlReader;
childRepeater.DataBind();
}
else
{
childRepeater.DataSource = "";
childRepeater.DataBind();
}
}
}
Everything up to this point works fine. I get my Genre groups and within each Genre I get the movie titles that are flagged against that Genre, and also the Linkbutton against each movie title. It's the LinkButton that is NOT firing the OnClick event.
Here is the code i'm using for the OnClick event.
protected void LoadMovieTitle (Object sender, EventArgs e)
{
LinkButton linkb = (LinkButton)(sender);
string args = linkb.CommandArgument;
Response.Redirect("movieinfopage.aspx?id=" + args);
}
The solution I am hoping to get help with is what do I need to do in order for those LinkButtons to fire their OnClick event when clicked, and access LoadMovieTitle. When I put a break in this method, it does not break, telling me that the OnClick event is not finding or recognising it.
You need to add OnItemCommand to repeater and CommandName to LinkButton:
<asp:Repeater ID="RepeaterMovies" runat="server" OnItemCommand="RepeaterMovies_OnItemCommand">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "MovieName") %>
<asp:LinkButton ID="lbMovieInfo" runat="server" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "MovieID") %>' CommandName="MovieDetail">
Access Info
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
Server side:
protected void RepeaterMovies_OnItemCommand(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandName.Equals("MovieDetail"))
{
LinkButton linkb = (LinkButton)(sender);
string args = linkb.CommandArgument;
Response.Redirect("movieinfopage.aspx?id=" + args);
}
}
See:
https://learn.microsoft.com/en-us/aspnet/web-forms/overview/data-access/custom-button-actions-with-the-datalist-and-repeater/custom-buttons-in-the-datalist-and-repeater-cs

How do I show an associated value with a dropdown list item (after choosing it from the list)?

I am programming in ASP.NET, visual studio. I have a dropdown list created in HTML form. If I dropdown the list, it displays the record from associated column in the table. But what I want is to show the corresponding value / record with that list item.
For example in the table, I have column id, productname and price. After choosing a particular product name (from drop down list), the associated price with it must be displayed in front of it (in a label).
However, By default, I want the drop down list to shows nothing in the beginning.
UPDATE:
Store.aspx:
<form id="form1" runat="server">
<div>
Welcome
<asp:Label ID="Label3" runat="server" ></asp:Label>
<br />
<br />
Products: <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" ></asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>" SelectCommand="SELECT * FROM [productdata]"></asp:SqlDataSource>
Price:
<asp:Label ID="Label1" runat="server" ></asp:Label>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Add to Cart" />
<br />
<br />
Items in cart: <asp:DropDownList ID="DropDownList2" runat="server"></asp:DropDownList>
<br />
<br />
Total Price: <asp:Label ID="Label2" runat="server"></asp:Label>
</div>
</form>
Store.aspx.cs:
public partial class Store : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label3.Text = Request.QueryString["name"];//show welcome text
String cs = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
if (!IsPostBack)
{
using (SqlConnection sc = new SqlConnection(cs))
{
SqlCommand sqlcom = new SqlCommand("Select id, productname, price from productdata", sc);
sc.Open();
DropDownList1.DataTextField = "productname";//show in the dropdown list
DropDownList1.DataValueField = "price"; //show in the label
DropDownList1.DataSource = sqlcom.ExecuteReader();
DropDownList1.DataBind();
}
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
String cs = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlDataReader rd;
using (SqlConnection sc = new SqlConnection(cs))
{
SqlCommand sqlcom = new SqlCommand("Select id, productname, price from productdata where id=" + Convert.ToUInt32(DropDownList1.SelectedValue), sc);
sc.Open();
rd = sqlcom.ExecuteReader();
if (rd.Read())
{
Label1.Text = rd[2].ToString();
}
sc.Close();
}
}
}
Database:
CREATE TABLE [dbo].[productdata] (
[Id] INT NOT NULL,
[productname] VARCHAR (50) NULL,
[price] FLOAT (53) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
This Edit according to using AutoPostBack=True and if (!IsPostBack) in Page_Load thanks to Arindam:
For simply solution using postback event:
First you should add OnSelectedIndexChanged event for dropdownlist
<asp:DropDownList ID="DropDownList1" runat="server"
OnSelectedIndexChanged="GetPrice" AutoPostBack="true">
</asp:DropDownList>
Then in code behind you just get selected value and fill to the label price
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Label3.Text = Request.QueryString["name"];//show welcome text
String cs = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using (SqlConnection sc = new SqlConnection(cs))
{
SqlCommand sqlcom = new SqlCommand("Select id, productname, price from productdata", sc);
sc.Open();
DropDownList1.DataTextField = "productname";//show in the dropdown list
DropDownList1.DataValueField = "price"; //show in the label
DropDownList1.DataSource = sqlcom.ExecuteReader();
DropDownList1.DataBind();
}
}
}
protected void GetPrice(object sender, EventArgs e)
{
Label1.Text = DropDownList1.SelectedValue;
}
You have to use AutoPostBack=True so that when you change index of dropdownlist, it will trigger a postback to server so the function GetPrice(...) will be called.
Every time the page postback, it will call function Page_Load(...) first, so you must use propertive IsPostBack to check if case1_this is the first time the page is loaded, or case2_a postback event, and you only set the ddl datasource at case1 because if you set datasource, by default the dropdownlist will reset to select first item in list.
When you go advance, you should consider using Javascript and Jquery to solve this, so the page will not load again like this postback solution.
And one more thing, you should name your controls well, don't make them default like that. It's one of two hard things in programming.
Yes you can but if not please use datatable and i am sure that work fine .if u not able do that just post I will give the correction.

Nesting Repeater Throws Casting Error

I currently have a parent repeater and two child repeaters on my page. I am wanting to dynamically pull data from our database and display them within the repeaters. I followed the Microsoft guide and a few SO questions on how to do this, and this is what I have arrived at:
<!-- start parent repeater -->
<asp:repeater id="parentRepeater" runat="server">
<itemtemplate>
<li><div id="et_<%# DataBinder.Eval(Container.DataItem,"EquipmentTypeName") %>"><%# DataBinder.Eval(Container.DataItem,"EquipmentTypeName") %><label><input type="checkbox"></label></div><ul runat="server">
<!-- start child repeater1 -->
<asp:repeater id="Repeater1" datasource='<%# ((DataRowView)Container.DataItem).Row.GetChildRows("myrelation") %>' runat="server">
<itemtemplate>
<li><div id="et_<%# DataBinder.Eval(Container.DataItem, "[\"MakeID\"]")%>"><%# DataBinder.Eval(Container.DataItem, "[\"MakeID\"]")%><label><input type="checkbox"></label></div><ul runat="server">
<!-- start child repeater2 -->
<asp:repeater id="childRepeater2" datasource='<%# ((DataRowView)Container.DataItem).Row.GetChildRows("myrelation2") %>' runat="server">
<itemtemplate>
<li><div id="et_<%# DataBinder.Eval(Container.DataItem, "[\"YearID\"]")%>"><%# DataBinder.Eval(Container.DataItem, "[\"YearID\"]")%><label><input type="checkbox"></label></div><ul runat="server">
</ul></li></itemtemplate>
</asp:repeater>
<!-- end child repeater2 -->
</ul></li></itemtemplate>
</asp:repeater>
<!-- end child repeater1 -->
</ul></li></itemtemplate>
</asp:repeater>
<!-- end parent repeater -->
And the code behind is as follows:
protected void Page_Load(object sender, EventArgs e)
{
//Create the connection and DataAdapter for the Authors table.
string Connection = WebConfigurationManager.ConnectionStrings["md_dbConnectionString"].ConnectionString;
SqlConnection cnn = new SqlConnection(Connection);
SqlDataAdapter cmd1 = new SqlDataAdapter("select * from EquipmentType", cnn);
//Create and fill the DataSet.
DataSet ds = new DataSet();
cmd1.Fill(ds, "EquipmentType");
SqlDataAdapter cmd2 = new SqlDataAdapter("select * from Make", cnn);
cmd2.Fill(ds, "Make");
//Create a second DataAdapter for the Titles table.
SqlDataAdapter cmd3 = new SqlDataAdapter("select distinct MakeID, TypeID, YearID from Parts", cnn);
cmd3.Fill(ds, "Parts");
//Create the relation bewtween the Authors and Titles tables.
ds.Relations.Add("myrelation",
ds.Tables["EquipmentType"].Columns["EquipmentTypeID"],
ds.Tables["Parts"].Columns["TypeID"]);
ds.Relations.Add("myrelation2",
ds.Tables["Make"].Columns["MakeID"],
ds.Tables["Parts"].Columns["MakeID"]);
//Bind the Authors table to the parent Repeater control, and call DataBind.
parentRepeater.DataSource = ds;
Page.DataBind();
//Close the connection.
cnn.Close();
}
If I load the page with only one child repeater, everything works fine, I get the correct data displaying, but when I add the second child repeater in, I get the following error message: Unable to cast object of type 'System.Data.DataRow' to type 'System.Data.DataRowView'. This fires on thedatasource='<%# ((DataRowView)Container.DataItem).Row.GetChildRows("myrelation2") %>'` ASP line.
The tables that I am trying to pull from are structured this way:
EquipmentType
EquipmentTypeID | EquipmentTypeName
Make
MakeID | MakeName
Year
YearID
Parts
PartID | MakeID | YearID | TypeID
Each table references the Parts table.
More or less what I want the repeater to do is display all of the EquipmentTypes, then only display the make is we have a part for it in the database. Once the make is selected, then only display the year that we have parts for that make and equipmenttype in the database.
Did you try to cast it to DataRow:
<%# ((DataRow)Container.DataItem).GetChildRows("myrelation2") %>
For anyone else experiencing this issue. It could be that there is a missing tag at the top of the page. <%# Import Namespace="System.Data" %>

Bind RadiobuttonList inside DataList

Good morning .
I search many times before posting here .
I am working on a project like a survey [Questions and Answers]
I am able to get all questions in datalist , now i am searching a way to display the answers in Radio button list inside each question .
here is page load
protected void Page_Load(object sender, EventArgs e)
{
string CS = ConfigurationManager.ConnectionStrings["TMConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(CS);
//Getting All Questions
SqlDataAdapter dr = new SqlDataAdapter("select * from Question ", con);
DataSet ds = new DataSet();
dr.Fill(ds, "Qs");
OuterDataList.DataSource = ds.Tables["Qs"];
OuterDataList.DataBind();
}
here is page body
<body>
<form id="form1" runat="server">
<h1>Test Page</h1>
<asp:DataList ID="OuterDataList" RunAt="server">
<ItemTemplate>
<h4><%# DataBinder.Eval (Container.DataItem, "Question") %></h4>
<asp:RadioButtonList ID="RadioButtonList1" runat="server"></asp:RadioButtonList>
</ItemTemplate>
</asp:DataList>
</form>
i dont know how to bind radiobuttonlist and group the answers .
note : the common column between Question table and Answer table is Question_id
Firt will make a template like below.
<asp:DataList runat="server" ID="DataList1" RepeatDirection="Vertical"
DataKeyField="QuestionID" onitemdatabound="DataList1_ItemDataBound">
<ItemTemplate>
<table>
<tr>
<td>
<%# Eval("Question") %>
</td>
</tr>
<tr>
<td>
<asp:RadioButtonList runat="server" ID="RadioButtonList1">
</asp:RadioButtonList>
</td>
</tr>
</table>
</ItemTemplate>
After that using DataList1_ItemDataBound you can bind your answers.
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item)
{
RadioButtonList RadioButtonList1 = (RadioButtonList)e.Item.FindControl("RadioButtonList1");
//Get questionID here
int QuestionID = Convert.ToInt32(DataBinder.Eval(e.Item.DataItem, "QuestionID"));
//pass Question ID to your DB and get all available options for the question
//Bind the RadiobUttonList here
}
}

dropdown list does not let select items properly

I am making a project in ASP.NET WebForms. Although I have done it so many times but dropdown list is troubling me a lot this time.
I fetch items from DB and then add them to my dropdown list one by one using FOR loop. That works fine. But the problem is that I cannot select an item from list comfortably, whenever I try to select an item from the drop down list, it snaps the selection to the first element, it becomes very difficult to select the desired item.
How could I fix that?
Suppose I move my cursor over the 9th item in the list then also it selects the 1st and 9th item alternatively so fast that I see both of them as selected.
CodeBehind
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DropDownList1.Items.Clear();
con.ConnectionString = ConfigurationManager.ConnectionStrings["familyConnectionString"].ConnectionString;
con.Open();
adp = new SqlDataAdapter("select distinct family_head from family", con);
DataSet ds = new DataSet();
adp.Fill(ds, "family");
con.Close();
for (int i = 0; i < ds.Tables["family"].Rows.Count; i++)
DropDownList1.Items.Add(ds.Tables["family"].Rows[i][0].ToString());
}
}
ASPX
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:DropDownList ID="DropDownList1" runat="server" Width="150px">
</asp:DropDownList>
<asp:DropDownList ID="DropDownList2" runat="server" Width="150px">
</asp:DropDownList>
<asp:Button ID="Button1" runat="server" Height="30px" onclick="Button1_Click"
Text="Submit" Width="145px" BackColor="#465767" ForeColor="White" />
<asp:RoundedCornersExtender ID="Button1_RoundedCornersExtender" runat="server"
Enabled="True" TargetControlID="Button1" Corners="All" Radius="10">
</asp:RoundedCornersExtender>
<br />
<br />
<br />
</asp:Content>
A CSS Keyframes Animation is working in page background, Can that be a cause?
There seems to be some kind of confusion, as to how databinding works for WebControls. The best reference for that is: http://msdn.microsoft.com/en-us/library/ms178472.aspx
Under the assumption, that all the binding code for DropDownList1 is shown:
DropDownList1.Items.Clear();
shouldn't be neccesary, as the items shouldn't persist per PostBack. (At least I assume that, because all Items will be lost after each PostBack if the DataSource isn't bound again).
The DropDownList needs have the items on each PostBack, if you want to use the DropDownList. You are using
if (!Page.IsPostBack)
which means, that you don't bind the items again, if you have a PostBack. In the link posted above, you can see that Controls set their properties (like which item was selected before clicking a Button) during the LoadEvent, which means that the items need to be binded earlier in the lifecycle, like during OnInit.
Try something like this:
protected void BindDropDownList1()
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["familyConnectionString"].ConnectionString;
con.Open();
adp = new SqlDataAdapter("select distinct family_head from family", con);
DataSet ds = new DataSet();
adp.Fill(ds, "family");
con.Close();
for (int i = 0; i < ds.Tables["family"].Rows.Count; i++)
DropDownList1.Items.Add(ds.Tables["family"].Rows[i][0].ToString());
}
protected override void OnInit(EventArgs e)
{
this.BindDropDownList1();
base.OnInit(e);
}
Another suggestion would be to you the DataSource property of the DropDownList, instead of DropDownList1.Items.Add. If you use this approach, you need to set the DataKeyValue and DataKeyMember properties of the DropDownList:
protected void BindDropDownList1()
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["familyConnectionString"].ConnectionString;
con.Open();
adp = new SqlDataAdapter("select distinct family_head from family", con);
DataSet ds = new DataSet();
adp.Fill(ds, "family");
con.Close();
DropDownList1.DataSource = ds;
DropDownList1.DataBind();
}
Edit:
I think I found your error. You are using controls from the AjaxControlToolKit, but are still using the ScriptManager. For about 2 years, controls from the AjaxControlToolKit require the ToolkitScriptManager. Replace the ScriptManager with a ToolkitScriptManager.

Categories

Resources