I have issue on doing the foreach part, I have multiple dropdownlist attach together with a textbox for filling quantity
But with my current code it will have issue with running all value in the foreach textbox first just until the next foreach of dropdownlist. Below is my code of now.
foreach (DropDownList dropDown in pnlDDLDispensary.Controls.OfType<DropDownList>()){foreach (TextBox textBox in pnltxtDispensaryQty.Controls.OfType<TextBox>()){ code here }}
My objective is want to insert each of the dropdownlist dispensary together with the quantity of that dispensary like example: (MedicineA with 5 quantity, MedicineB with 1 quantity). Is there anything like foreach( a in control && b in control)? Appreciate for help. Thanks~
protected void cmdDelete_ServerClick(object sender, EventArgs e)
{
GridToTable(); //This function havent done due to also having DataKeys cannot used like a method error
Button btnDelete = (Button)sender;
ListViewItem gRow = (ListViewItem)btnDelete.NamingContainer;
int disID = lvDispensary.DataKeys(gRow.DataItemIndex).Item("dispensaryID");
}
Result:
CS1955: Non-invocable member 'ListView.DataKeys' cannot be used like a method.
It not at all clear what kind of "system" or choice you have made to show the repeating drop down and text box.
As a general rule, if you need to "repeat" controls, then you use a listview, repeater, or even maybe a grid view.
so it will not matter if you have 1 or 15 row of repeating data (you don't care how many).
So, I might say have 1 or 8 hotels, and I have a combo box to rate the hotel.
So, hum, lets use the repeater.
So, we only need to drop/have one instance of the markup layout.
Say, like this:
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<asp:Label ID="lblH" runat="server" Text="Hotel Name" Font-Size="Medium">
</asp:Label>
<asp:TextBox ID="txtHotel" runat="server"
Text = '<%# Eval("HotelName") %>'
style="margin-left:20px" >
</asp:TextBox>
<asp:DropDownList ID="DropDownList1" runat="server"
style="margin-left:20px;width:120px"
DataValueField = "ID"
DataTextField = "Rating" >
</asp:DropDownList>
<br />
</ItemTemplate>
</asp:Repeater>
and our code behind is this:
DataTable rstRating = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
// set combo box source
rstRating =
MyRst("SELECT ID, Rating FROM tblRating ORDER BY ID");
DataTable rstData =
MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
Repeater1.DataSource = rstData;
Repeater1.DataBind();
}
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item |
e.Item.ItemType == ListItemType.AlternatingItem)
{
DropDownList dl = (DropDownList)e.Item.FindControl("DropDownList1");
dl.DataSource = rstRating;
dl.DataBind();
dl.Items.Insert(0, new ListItem("Please Select", "0"));
}
}
and now we get this:
so, above works for 2 or 20 rows of data. We don't care how many rows.
but, now to do a for each on the repeating controls?
This:
protected void Button1_Click(object sender, EventArgs e)
{
foreach (RepeaterItem OneRow in Repeater1.Items)
{
TextBox txtHotel = (TextBox)OneRow.FindControl("txtHotel");
DropDownList cboRate = (DropDownList)OneRow.FindControl("DropDownList1");
Debug.Print("Hotel name = " + txtHotel.Text + " -- Rating = " +
cboRate.SelectedItem.Text);
}
}
And output is this:
So, for a "set" or "thing" of repeating data, then use some type of control such as a repeater.
I mean, for above, we could also use a listview, and that also is quite nice, say like this:
<div style="width:24%">
<asp:ListView ID="LVHotels" runat="server" DataKeyNames="ID" OnItemDataBound="LVHotels_ItemDataBound" >
<ItemTemplate>
<tr style="">
<td>
<asp:TextBox ID="txtHotel" runat="server"
Text = '<%# Eval("HotelName") %>'
style="margin-left:20px" >
</asp:TextBox>
</td>
<td>
<asp:DropDownList ID="DropDownList1" runat="server"
style="margin-left:20px;width:120px"
DataValueField = "ID"
DataTextField = "Rating" >
</asp:DropDownList>
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" class="table table-bordered">
<tr runat="server" style="">
<th runat="server">Hotel Name</th>
<th runat="server">Rating</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
</div>
Same code to bind, and we now have this:
And then once again, our for each code against that listview is much the same.
So, the idea here?
If you have repeating controls, then use some type of gridview, repeater, or listview.
that way, its all data driven, and once done, then 2 or 20 rows - it don't matter, and you can use for each against these containers that repeated the data for you.
Edit: User wants a List View example.
Ok, so markup for this is this:
<div style="width:30%">
<style>
.borderhide input {border:none;background-color:transparent}
.borderhide textarea {border:none;background-color:transparent}
</style>
<asp:ListView ID="LVHotels" runat="server" DataKeyNames="ID" OnItemDataBound="LVHotels_ItemDataBound" >
<ItemTemplate>
<tr style="">
<td><asp:TextBox ID="txtFirst" runat="server" Text='<%# Eval("FirstName") %>' width="80px"></asp:TextBox></td>
<td><asp:TextBox ID="txtLast" runat="server" Text='<%# Eval("LastName") %>' width="80px"></asp:TextBox></td>
<td><asp:TextBox ID="txtHotel" runat="server" Text='<%# Eval("HotelName") %>' width="110px"></asp:TextBox></td>
<td>
<asp:DropDownList ID="DropDownList1" runat="server"
style="width:120px"
DataValueField = "ID"
DataTextField = "Rating" >
</asp:DropDownList>
</td>
<td>
<button id="cmdDelete" runat="server" class="btn"
onserverclick="cmdDelete_ServerClick"
onclick="if (!confirm('Really delete')) {return false}" >
<span aria-hidden="true" class="glyphicon glyphicon-trash"></span>
</button>
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" class="table table-bordered borderhide">
<tr runat="server" style="">
<th runat="server">First Name</th>
<th runat="server">Last Name</th>
<th runat="server">Hotel Name</th>
<th runat="server">Rating</th>
<th runat="server"></th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
<tfoot><tr><td>
<button id="cmdAddNew" runat="server" class="btn" onserverclick="cmdAddNew_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-plus-sign"> New</span>
</button>
</td></tr></tfoot>
</table>
</LayoutTemplate>
</asp:ListView>
</div>
<br />
<button id="cmdSave" runat="server" class="btn" onserverclick="cmdSave_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-floppy-saved"> Save</span>
</button>
<button id="cmdCancel" runat="server" class="btn" style="margin-left:15px" onserverclick="cmdCancel_ServerClick">
<span aria-hidden="true" class="glyphicon glyphicon-arrow-left"> Back/Cancel</span>
</button>
</div>
And our full code for this is this:
DataTable rstRating = new DataTable();
DataTable rstData = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadData();
Session["rstData"] = rstData;
Session["rstRating"] = rstRating;
}
else
{
rstData = (DataTable)Session["rstData"];
rstRating = (DataTable)Session["rstRating"];
}
}
void LoadData()
{
// set combo box source
rstRating = MyRst("SELECT ID, Rating FROM tblRating ORDER BY ID");
rstData = MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
LVHotels.DataSource = rstData;
LVHotels.DataBind();
}
DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
protected void LVHotels_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
DropDownList dl = (DropDownList)e.Item.FindControl("DropDownList1");
dl.DataSource = rstRating;
dl.DataBind();
dl.Items.Insert(0, new ListItem("Please Select", "0"));
// now set to current data row
DataRowView OneRow = (DataRowView)e.Item.DataItem;
if (OneRow["Rating"] != null)
dl.SelectedValue = OneRow["Rating"].ToString();
}
}
protected void cmdSave_ServerClick(object sender, EventArgs e)
{
SaveAllData();
// data saved - move on to next page
// Response.Redirect("MyMain.aspx");
}
protected void cmdAddNew_ServerClick(object sender, EventArgs e)
{
DataRow NewRow = rstData.NewRow();
rstData.Rows.Add(NewRow);
// show this row
LVHotels.DataSource = rstData;
LVHotels.DataBind();
}
void SaveAllData()
{
GridToTable(); // move grid back to table
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL =
new SqlCommand("SELECT * FROM tblHotelsA WHERE ID = 0", conn))
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daU = new SqlCommandBuilder(da);
da.Update(rstData);
// rstData.AcceptChanges()
}
}
}
protected void cmdCancel_ServerClick(object sender, EventArgs e)
{
// cancel without save - go back some place to other page
// Response.Redirect("MyMain.aspx");
}
void GridToTable()
{
// send LV rows back to our table.
foreach (ListViewItem rRow in LVHotels.Items)
{
int RecordPtr = rRow.DataItemIndex;
DataRow OneDataRow = rstData.Rows[RecordPtr];
OneDataRow["FirstName"] = ((TextBox)rRow.FindControl("txtFirst")).Text;
OneDataRow["LastName"] = ((TextBox)rRow.FindControl("txtLast")).Text;
OneDataRow["HotelName"] = ((TextBox)rRow.FindControl("txtHotel")).Text;
DropDownList dlRating = (DropDownList)rRow.FindControl("DropDownList1");
if (dlRating.SelectedIndex == 0)
OneDataRow["Rating"] = null;
else
OneDataRow["Rating"] = dlRating.SelectedItem.Value;
}
}
protected void cmdDelete_ServerClick(object sender, EventArgs e)
{
// we actully should saveAllData before we do this
// we might have added rows without save and thus
// pk not correctly valid
// so we need to actaully check deleted row status here.
HtmlButton btn = (HtmlButton)sender;
ListViewItem gRow = (ListViewItem)btn.NamingContainer;
int RowIndex = gRow.DataItemIndex;
int PK = (int)LVHotels.DataKeys[RowIndex]["ID"];
string strSQL = "DELETE FROM tblHotelsA WHERE ID = " + PK;
Debug.Print("will delete - future code");
}
And we now have get this:
So, you can:
Tab around - edit + change any row - including combo box
Add new rows
THEN hit save button, all edits, adding, edits and even delete(s) will now go back to sql server table.
The data bound event for the listview in above is what you are looking for.
Only part left out is delete button - but that should be easy.
Edit3: adding the delete button code
As noted, if we are to allow delete, then we STILL have to hit the save button, and the un-do changes button WILL still work!!! So, the user can add a few rows, delete a few rows - and then go "opps" wrong rows deleted. Since we not yet hit save, then we not actaully deleted the data. (and this means our un-do button can still work).
But, what this means? well in rstData, then rows of DELETED data WILL exist. We can feed rstData to the LV, and such rows don't show.
But, using for/each on the rstData? Then YES DELETED rows will show up!
And if the LV displays 5 rows, but we had 10 and deleted 5 of them?
Then as noted, we NOW cannot USE the LV "index" to peek into rstData anymore. But, we can still use Datakeys. BEYOND critial then that you set datakeys setting in the LV markup as I have done above.
So, first up, the delete button code. User might bounce around, edit some rows, maybe add. But then hits delete button.
So, this code is easy. (also note the JavaScript confirm prompt to confirm the delete button).
hence this:
Protected Sub cmdDelete_ServerClick(sender As Object, e As EventArgs)
' save any edits BACK to table before delete
' this ONLY delets from persited table - not SQL server.
GridToTable()
Dim btn As HtmlButton = sender
Dim gRow As ListViewItem = btn.NamingContainer
Dim PK As Integer = ListView1.DataKeys(gRow.DataItemIndex).Item("ID")
Dim OneDataRow As DataRow = rstData.Select("id = " & PK)(0)
OneDataRow.Delete()
DisplayUpdate()
End Sub
Note VERY close in above. We did not (and can't) use the LV index into our table, since rstData now can have more rows then the LV display. (LV is smart, only display rows that are not deleted).
So, in above, we dumped "index" from LV into rstData, and we now use PK value.
This also now means our GridToTable can't use the simple "index" into rstdata, and we MUST pull each row from rstData by PK value (we have to search/find the PK row based on PK).
So, GridToTable now has to be this:
Sub GridToTable()
' send grid rows back to persited table
For Each gRow As ListViewItem In ListView1.Items
' Get database PK value
Dim PK As Integer = ListView1.DataKeys(gRow.DataItemIndex).Item("ID")
Dim drT() As DataRow = rstData.Select("ID = " & PK, "", DataViewRowState.CurrentRows)
If drT.Length > 0 Then
Dim OneDataRow As DataRow
OneDataRow = drT(0)
OneDataRow.Item("FirstName") = CType(gRow.FindControl("txtFirst"), TextBox).Text
OneDataRow.Item("LastName") = CType(gRow.FindControl("txtLast"), TextBox).Text
OneDataRow.Item("City") = CType(gRow.FindControl("txtCity"), TextBox).Text
OneDataRow.Item("Description") = CType(gRow.FindControl("txtDescription"), TextBox).Text
OneDataRow.Item("Nights") = CType(gRow.FindControl("txtNights"), TextBox).Text
' combo box
Dim cboRank As DropDownList = gRow.FindControl("cboRank")
If cboRank.Text = "Select" Then
OneDataRow("Rating") = DBNull.Value
Else
OneDataRow("Rating") = cboRank.SelectedItem.Value
End If
End If
Next
End Sub
Note how we dumped "index" and now do search by PK. (note that datakeys by index WILL be ok, since LV only displays rows not deleted.
Edit4: Delete code - full code listing
As noted, I did post some vb code by mistake.
So, here is the full code listing:
DataTable rstRating = new DataTable();
DataTable rstData = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadData();
Session["rstData"] = rstData;
Session["rstRating"] = rstRating;
}
else
{
rstData = (DataTable)Session["rstData"];
rstRating = (DataTable)Session["rstRating"];
}
}
void LoadData()
{
// set combo box source
rstRating = MyRst("SELECT ID, Rating FROM tblRating ORDER BY ID");
rstData = MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
LVHotels.DataSource = rstData;
LVHotels.DataBind();
}
DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
protected void LVHotels_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
DropDownList dl = (DropDownList)e.Item.FindControl("DropDownList1");
dl.DataSource = rstRating;
dl.DataBind();
dl.Items.Insert(0, new ListItem("Please Select", "0"));
// now set to current data row
DataRowView OneRow = (DataRowView)e.Item.DataItem;
if (OneRow["Rating"] != null)
dl.SelectedValue = OneRow["Rating"].ToString();
}
}
protected void cmdSave_ServerClick(object sender, EventArgs e)
{
SaveAllData();
// data saved - move on to next page
// Response.Redirect("MyMain.aspx");
}
protected void cmdAddNew_ServerClick(object sender, EventArgs e)
{
DataRow NewRow = rstData.NewRow();
rstData.Rows.Add(NewRow);
// show this row
LVHotels.DataSource = rstData;
LVHotels.DataBind();
}
void SaveAllData()
{
GridToTable(); // move grid back to table
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL =
new SqlCommand("SELECT * FROM tblHotelsA WHERE ID = 0", conn))
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daU = new SqlCommandBuilder(da);
da.Update(rstData);
// rstData.AcceptChanges()
}
}
}
protected void cmdCancel_ServerClick(object sender, EventArgs e)
{
// cancel without save - go back some place to other page
// Response.Redirect("MyMain.aspx");
}
void GridToTable()
{
// send LV rows back to our table.
foreach (ListViewItem rRow in LVHotels.Items)
{
int PK = (int)LVHotels.DataKeys[rRow.DisplayIndex]["ID"];
// get row by PK
DataRow[] drT = rstData.Select("ID = " + PK,"", DataViewRowState.CurrentRows);
if (drT.Length > 0)
{
DataRow OneDataRow = drT[0];
OneDataRow["FirstName"] = ((TextBox)rRow.FindControl("txtFirst")).Text;
OneDataRow["LastName"] = ((TextBox)rRow.FindControl("txtLast")).Text;
OneDataRow["HotelName"] = ((TextBox)rRow.FindControl("txtHotel")).Text;
DropDownList dlRating = (DropDownList)rRow.FindControl("DropDownList1");
if (dlRating.SelectedIndex == 0)
OneDataRow["Rating"] = DBNull.Value;
else
OneDataRow["Rating"] = dlRating.SelectedItem.Value;
}
}
}
protected void cmdDelete_ServerClick(object sender, EventArgs e)
{
GridToTable();
HtmlButton btn = (HtmlButton)sender;
ListViewItem gRow = (ListViewItem)btn.NamingContainer;
int PK = (int)LVHotels.DataKeys[gRow.DataItemIndex]["ID"];
// get row by PK
DataRow[] drT = rstData.Select("ID = " + PK, "", DataViewRowState.CurrentRows);
drT[0].Delete();
LVHotels.DataSource = rstData;
LVHotels.DataBind();
}
protected void cmdUndo_ServerClick(object sender, EventArgs e)
{
LoadData();
Session["rstData"] = rstData;
}
And the results look like this:
Markup for the buttons was:
<br />
<button id="cmdSave" runat="server" class="btn" onserverclick="cmdSave_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-floppy-saved"> Save</span>
</button>
<button id="cmdCancel" runat="server" class="btn" style="margin-left:15px" onserverclick="cmdCancel_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-arrow-left"> Back/Cancel</span>
</button>
<button id="cmdUndo" runat="server" class="btn" style="margin-left:15px"
onserverclick="cmdUndo_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-refresh"> Undo Edits</span>
</button>
And I was going to add a bootstrap dialog for confirms - the built in browser ones look beyond ugly. But above should clear up the syntax for htis to work.
I am developing an application (Quiz Engine) in Asp.Net with C#. I have a database table (Q_ID,Question,option1,option2,option3,answer).
What I want is, to retrieve these data and display to the user as Question and Answer and enable the user to select with the Radio button. My problem is that how I can display this Question and options in radiobuttonlist.
my asp page is
<asp:DataList ID="DataList2" runat="server" RepeatDirection="Vertical">
<ItemTemplate>
<br />
<table class="auto-style1">
<tr>
<td>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("Question") %>'></asp:Label>
</td>
<td>
<asp:RadioButtonList ID="RadioButtonList2" runat="server">
</asp:RadioButtonList>
</td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
and my cod behind is like
public partial class WebForm3 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindData();
}
}
private void BindData()
{
DataTable dt = new DataTable();
string connStr = #"Data Source=localhost;Database=ahsschema;User Id=webuser;Password=webuser2014";
using (MySqlConnection cn = new MySqlConnection(connStr))
{
MySqlDataAdapter adp = new MySqlDataAdapter("select LO_id,Q_Id,level,Question,option1,option2 from quiz WHERE LO_id='LO111'", cn);
adp.Fill(dt);
}
if (dt.Rows.Count > 0)
{
DataList2.DataSource = dt;
DataList2.DataBind();
}
foreach (DataListItem dli in DataList2.Items)
{
RadioButtonList RadioButtonList2 = (RadioButtonList)DataList2.FindControl("RadioButtonList2");
//RadioButtonList2.Items.Clear();
RadioButtonList2.Items.Insert(0, new ListItem("option1".ToString(), "option1".ToString()));
RadioButtonList2.Items.Insert(1, new ListItem("option2".ToString(), "option2".ToString()));
}
}
In my <asp:Repeater></asp:Repeater> - There is one hidden field, textbox and button.
When data will be bound, then hidden filed will get User Id like below code
<asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server"/>
and ItemDataBound event will be called and in this function, i am getting value from hidden field and concatenating that value as a Id in text box. like below code
TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
HiddenField hf = (HiddenField)e.Item.FindControl("hide");//1
txt.ID = "txtReplyArea" + hf.Value;//txtReplyArea1
Suppose only one record comes from database and their UserId is 1. Then textbox Id should be "textReplyArea1". From now, all are correct.
I am not sure, it's correct way to giving dynamic Id to repeater control but i think, it's correct.
Problem -
When i click on button and i get a items from repeater and textbox from Id by finding control from repeater then it shows null.
int areaId = int.Parse((sender as Button).CommandArgument);//1
string id="txtReplyArea"+areaId;//txtReplyArea1
foreach (RepeaterItem item in repeaterBlog.Items)
{
TextBox tb = item.FindControl(id) as TextBox;//tb = null
}
Code of aspx page
<%# Page Title="Messages" Language="C#" MasterPageFile="~/Menu.master" AutoEventWireup="true" CodeFile="Messages.aspx.cs" Inherits="Messages" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div style="width:70%;">
<asp:Repeater ID="repeaterBlog" runat="server" OnItemDataBound="repeaterBlog_ItemDataBound">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr >
<td>
<asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server"/>
<asp:TextBox ID="txtReplyArea" runat="server" TextMode="Multiline" Columns="70" Rows="8" Visible="false"></asp:TextBox>
</td>
</tr>
<tr>
<td style="margin-left:47%;">
<asp:Button ID="btnReply" runat="server" Text="Reply" OnClick="btnReplyClicked" AutoPostBack="True" CommandArgument='<%#Eval("UserId")%>'/>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
</asp:Content>
Code of aspx.cs
SqlCommand cmd;
SqlDataReader sdr;
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
String cs = ConfigurationManager.ConnectionStrings["myWebsite"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
cmd = new SqlCommand("select * from ContactMessage", con);
con.Open();
sdr = cmd.ExecuteReader();
repeaterBlog.DataSource = sdr;
repeaterBlog.DataBind();
con.Close();
}
}
}
public void repeaterBlog_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
HiddenField hf = (HiddenField)e.Item.FindControl("hide");
txt.ID = "txtReplyArea" + hf.Value;
}
}
protected void btnReplyClicked(object sender, EventArgs e)
{
int areaId = int.Parse((sender as Button).CommandArgument);
string id="txtReplyArea"+areaId;
foreach (RepeaterItem item in repeaterBlog.Items)
{
TextBox tb = item.FindControl(id) as TextBox;
}
}
}
This worked for me. Notice that I removed EnableViewState from the repeater and added OnItemDatabound event.
<asp:Repeater ID="repeaterBlog" runat="server" OnItemDataBound="repeaterBlog_ItemDataBound">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server" />
<asp:TextBox ID="txtReplyArea" runat="server" TextMode="Multiline" Columns="70" Rows="8"
Visible="false"></asp:TextBox>
</td>
</tr>
<tr>
<td style="margin-left: 47%;">
<asp:Button ID="btnReply" runat="server" Text="Reply" OnClick="btnReplyClicked" AutoPostBack="True"
CommandArgument='<%#Eval("UserId")%>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("UserId");
DataRow dr = dt.NewRow();
dr[0] = 34;
dt.Rows.Add(dr);
repeaterBlog.DataSource = dt;
repeaterBlog.DataBind();
}
public void repeaterBlog_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
HiddenField hf = (HiddenField)e.Item.FindControl("hide");
txt.ID = "txtReplyArea" + hf.Value;
}
}
protected void btnReplyClicked(object sender, EventArgs e)
{
int areaId = int.Parse((sender as Button).CommandArgument);
string id = "txtReplyArea" + areaId;
foreach (RepeaterItem item in repeaterBlog.Items)
{
TextBox tb = item.FindControl(id) as TextBox;
}
}
You can try like this
<asp:TextBox ID='<%# "txtReplyArea" + Convert.ToString(Eval("UserId")%>)' runat="server" TextMode="Multiline" Columns="70" Rows="8" Visible="false"></asp:TextBox>
I bind the values in usercontrol dropdownlist
But when I add the usercontrol row that time values are not binded in dropdownlist
Code:
.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="TimesheetUserControl.ascx.cs" Inherits="Portal.TimesheetUserControl" %>
<table>
<tr>
<td>
<asp:DropDownList ID="DropDownActivities" Width="150px" runat="server"></asp:DropDownList>
</td>
<td>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="TextBox4" runat="server"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="TextBox5" runat="server"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="TextBox7" runat="server"></asp:TextBox>
</td>
</tr>
.aspx
<uc:Timesheet ID="Timesheet" runat="server" />
<asp:Repeater ID="rpt1" runat="server">
<ItemTemplate>
</ItemTemplate>
</asp:Repeater>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row" OnClick="ButtonAdd_Click"/>
.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback)
{
BindActivities();
}
}
protected void BindActivities()
{
DropDownList dropActivities = Timesheet.FindControl("DropDownActivities") as DropDownList;
DbConnection.Open();
OleDbCommand cmd1 = new OleDbCommand("select designation from emp_master where username = '" + username + "'", DbConnection);
OleDbDataAdapter da = new OleDbDataAdapter(Deptcmd);
DataSet ds = new DataSet();
da.Fill(ds);
// DbConnection.Close();
dropActivities.DataSource = ds;
dropActivities.DataTextField = "ActivityName";
dropActivities.DataBind();
dropActivities.Items.Insert(0, new ListItem("--Select--", "0"));
}
public List<string> NoOfControls
{
get
{
return ViewState["NoOfControls"] == null ? new List<string>() : (List<string>)ViewState["NoOfControls"];
}
set
{
ViewState["NoOfControls"] = value;
}
}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
if (IsPostBack)
{
GenerateControls();
}
}
private void GenerateControls()
{
foreach (string i in NoOfControls)
{
TimesheetUserControl ctrl = (TimesheetUserControl)Page.LoadControl("TimesheetUserControl.ascx");
ctrl.ID = i;
this.rpt1.Controls.Add(ctrl);
}
}
protected void ButtonAdd_Click(object sender, EventArgs e)
{
Button thisButton = (Button)sender;
List<string> temp = null;
var uc = (TimesheetUserControl)this.LoadControl(#"TimesheetUserControl.ascx");
string id = Guid.NewGuid().ToString();
uc.ID = id;
temp = NoOfControls;
temp.Add(id);
NoOfControls = temp;
rpt1.Controls.Add(uc);
}
In the below image if Click add button rows are added but in second values are not binded in dropdownlist
Any ideas? Thanks in advance.
find the user controls by the id you given and then you can find the DropDownList inside the usercontrol.
protected void BindActivities()
{
foreach (string controlName in NoOfControls)
{
TimesheetUserControl userControl = Timesheet.FindControl(controlName) as TimesheetUserControl;
if(userControl == null) return;
DropDownList dropActivities = userControl.FindControl("DropDownActivities") as DropDownList;
if(dropActivities == null) return;
DbConnection.Open();
OleDbCommand cmd1 = new OleDbCommand("select designation from emp_master where username = '" + username + "'", DbConnection);
OleDbDataAdapter da = new OleDbDataAdapter(Deptcmd);
DataSet ds = new DataSet();
da.Fill(ds);
// DbConnection.Close();
dropActivities.DataSource = ds;
dropActivities.DataTextField = "ActivityName";
dropActivities.DataBind();
dropActivities.Items.Insert(0, new ListItem("--Select--", "0"));
}
}
I've a listview that allows Editing and Delete.
When I Click on the linkbutton in the listview, it fires up page_load then to OnItemCommand.
At the end of the command I added DataBind Which does not refresh my listview but deleted my entry.
If I change the DataBind to Redirect back to the same page with (...aspx?ID=...) it will return me a fresh new page. but in debug mode, I saw it run through page_load and the Databind.
<asp:UpdatePanel ID="UpdateOptions" runat="server" >
<ContentTemplate>
<asp:Panel ID="OPanel" runat="server" width="350px">
<asp:ListView runat="server" ID="lvPollOptions" DataKeyNames="POptionID" OnItemCommand="lvPollOptions_ItemCommand" OnDataBound="lvPollOptions_ItemDataBound" >
<LayoutTemplate>
<table cellpadding="0" cellspacing="0" border="0" width="300px">
<tr class="AdminListHeader">
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<%#Eval("OptionText")%>
</td>
<td>
<%#Eval("Votes")%>
</td>
<td align="center">
<asp:ImageButton runat="server" ID="ibtnEditOption" CommandArgument='<%# Eval("POptionID").ToString() %>' CommandName="Edit" ImageUrl="~/images/buttons/EditPencil.gif" AlternateText="Edit" CssClass="AdminImg" />
</td>
<td>
<asp:ImageButton runat="server" ID="ibtnDeleteOption" CommandArgument='<%# Eval("POptionID").ToString() %>' CommandName="Delete" ImageUrl="~/images/buttons/delete.gif" AlternateText="Delete" CssClass="AdminImg" OnClientClick="return confirm('Warning: This will delete the Poll Option from the database.');" />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:Label ID="lblNoOption" runat="server" Text="No Options Added"></asp:Label>
<table width="345px">
<tr>
<td width="100px">
Option:
</td>
<td>
<asp:TextBox ID="txtOption" runat="server" width="200px"></asp:TextBox>
</td>
</tr>
</table>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
Code Behind
protected void PollBindData()
{
SqlConnection connOption = new SqlConnection(connStr);
connOption.Open();
SqlDataAdapter da = new SqlDataAdapter("SELECT POptionID, OptionText, Votes FROM [PollOptions] Where PollID = '" + PID + "'", connOption);
DataSet dsSel = new DataSet();
da.Fill(dsSel);
lvPollOptions.DataSource = dsSel;
lvPollOptions.DataBind();
connOption.Close();
}
protected void Page_Load(object sender, EventArgs e)
{
string PID = Request.QueryString["ID"];
if (!IsPostBack)
{
if (PID == null)
{
}
else if (PID != null)
{
PollBindData();
}
}
}
protected void lvPollOptions_ItemDataBound(object sender, ListViewItemEventArgs e)
{
string PID = Request.QueryString["ID"];
SqlConnection connOption = new SqlConnection(connStr);
connOption.Open();
SqlDataAdapter da = new SqlDataAdapter("SELECT POptionID, OptionText, Votes FROM [PollOptions] Where PollID = '" + PID + "'", connOption);
DataSet dsSel = new DataSet();
da.Fill(dsSel);
lvPollOptions.DataSource = dsSel;
lvPollOptions.DataBind();
connOption.Close();
}
protected void lvPollOptions_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
string selectedID = e.CommandArgument.ToString();
SqlConnection connDeleteOption = new SqlConnection(connStr);
connDeleteOption.Open();
SqlCommand cmdDeleteOption = new SqlCommand("DELETE FROM [PollOptions] WHERE POptionID = '" + selectedID + "'", connDeleteOption);
cmdDeleteOption.ExecuteNonQuery();
connDeleteOption.Close();
PollBindData();
//Response.Redirect("aAddEditPoll.aspx?ID=" + selectedID);
}
if (e.CommandName == "Edit")
{
string EditID = e.CommandArgument.ToString();
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
SqlCommand cmdView = new SqlCommand("SELECT OptionText From [PollOptions] Where POptionID = '" + EditID + "'", conn);
SqlDataReader dr1 = cmdView.ExecuteReader();
if (dr1.Read())
{
txtOption.Text = dr1["OptionText"].ToString();
}
Session["OptionID"] = txtOption.Text;
dr1.Close();
conn.Close();
lbOInsert.Visible = false;
lbOUpdate.Visible = true;
PollBindData();
//Response.Redirect("aAddEditPoll.aspx?ID=" + EditID);
}
}
Before we start - your code has a security risk since it is prone to Sql Injection, make sure you Parametrize your queries...
Now, your question is not very clear, but if I understand correctly, you're saying that after you delete an object, the Listview isn't refreshed after postback (e.g. you still see the deleted item). Since you're running in an UpdatePanel, make sure to update the panel after the DataBind...
Update PoolBindData like this
protected void PollBindData()
{
SqlConnection connOption = new SqlConnection(connStr);
connOption.Open();
// POTENTIAL SECURITY RISK - MAKE SURE YOU PARAMETRIZE THE QUERY!!
SqlDataAdapter da = new SqlDataAdapter("SELECT POptionID, OptionText, Votes FROM [PollOptions] Where PollID = '" + PID + "'", connOption);
DataTable dsSel = new DataTable();
da.Fill(dsSel);
lvPollOptions.DataSource = dsSel;
lvPollOptions.DataBind();
connOption.Close();
// Update panel
UpdateOptions.Update();
}