I have a PlaceHolder in a webform with Master page with the code
<asp:DropDownList ID="NoofSubjectList" runat="server"
AutoPostBack="true" OnSelectedIndexChanged="NoofSubject_Index_Changed">
<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>3</asp:ListItem>
<asp:ListItem>4</asp:ListItem>
<asp:ListItem>5</asp:ListItem>
<asp:ListItem>6</asp:ListItem>
<asp:ListItem>7</asp:ListItem>
<asp:ListItem>8</asp:ListItem>
<asp:ListItem>9</asp:ListItem>
<asp:ListItem>10</asp:ListItem>
<asp:ListItem>11</asp:ListItem>
<asp:ListItem>12</asp:ListItem>
</asp:DropDownList>
<asp:PlaceHolder ID="placeholder" runat="server" />
Based on the number(n) selected from the DropDownList (1), I will be Dynamically creating two sets of DropDownList (2,3) for the selected n numbers. In that the first DropDownList loads data from a database. The code is shown below,
protected void NoofSubject_Index_Changed(Object sender, EventArgs e)
{
int value = Convert.ToInt32(NoofSubjectList.SelectedItem.Text.ToString());
DataSet ds1 = new DataSet();
MySql.Data.MySqlClient.MySqlConnection mysqlConnection = new
MySql.Data.MySqlClient.MySqlConnection
("Database=school;Server=localhost;UID=root;PWD=;");
MySql.Data.MySqlClient.MySqlCommand mysqlCommand = new
MySql.Data.MySqlClient.MySqlCommand
("SELECT Dept FROM tabledept WHERE Status='Active'", mysqlConnection);
MySql.Data.MySqlClient.MySqlDataAdapter mysqlAdaptor = new
MySql.Data.MySqlClient.MySqlDataAdapter(mysqlCommand);
mysqlAdaptor.Fill(ds1);
for (int i = 0; i <= value - 1; i++)
{
DropDownList _SubList = new DropDownList();
_SubList.ID = "SubList" + (i + 1);
_SubList.Width= 75;
DropDownList _DeptList = new DropDownList();
_DeptList.ID = "DeptList" + (i + 1);
_DeptList.Width = 75;
_DeptList.SelectedIndexChanged += DeptList_Index_Changed;
Literal _spacer = new Literal();
_spacer.Text = "<br />";
Literal _spacerlbl = new Literal();
_spacerlbl.Text = " ";
Label _Lbl = new Label();
_Lbl.ID = "lbl_Subject" + i;
_Lbl.Text = "Subject" + (i+1);
Label _Lbl1 = new Label();
_Lbl1.ID = "lbl_Dept" + i;
_Lbl1.Text = "Department";
_DeptList.DataSource = ds1;
_DeptList.DataTextField = ds1.Tables[0].Columns["Dept"].ColumnName;
_DeptList.DataValueField = ds1.Tables[0].Columns["Dept"].ColumnName;
_DeptList.DataBind();
_DeptList.AutoPostBack = true;
placeholder.Controls.Add(_Lbl1);
placeholder.Controls.Add(_spacerlbl);
placeholder.Controls.Add(_DeptList);
placeholder.Controls.Add(_spacerlbl);
placeholder.Controls.Add(_Lbl);
placeholder.Controls.Add(_SubList);
placeholder.Controls.Add(_spacer);
}
}
protected void DeptList_Index_Changed(Object sender, EventArgs e)
{
\\Based on the selection in DropDownList2, a list will be loaded from a
\\database to DropDownList3
}
The above event is triggered based on the selection of the number n from the DropDownList (1). If I select an item from DropDownList (2) the data will be generated from database and added to the DropDownList (3) . The problem is when I try to select an item from DropDownList (2), the dynamically created controls get lost. How to overcome this issue?
I even googled it and I found out that I am missing something called PostBack in my code. But I could not able to find out relevant resource to learn about it
I got a link which shows an easy example of creating the controls after postback.
Creating Dynamic TextBox Controls using C#
Related
I have a DataList and bind it corrertly.
SqlCommand cmd = new SqlCommand(str_cmd, conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
dtlst_periodicTask.DataSource = ds;
dtlst_periodicTask.DataBind();
pds.DataSource = ds.Tables[0].DefaultView;
pds.AllowPaging = true;
pds.PageSize = 25;
pds.CurrentPageIndex = CurrentPage;
lnkbtnNext.Enabled = !pds.IsLastPage;
lnkbtnPrevious.Enabled = !pds.IsFirstPage;
and some codes for paging.
After that, I need to add a number of Buttons in each row dynamically because the number of buttons is not fix.
foreach (DataListItem item in dtlst.Items)
{
Button btn = new Button();
btn.Click += new EventHandler(btn_Click);
pnl_users.Controls.Add(btn);
}
But the button click event does not work.
protected void btn_Click(object sender, EventArgs e)
{
// code does not fire.
}
When I put a Button in .aspx page, have access and it works.
protected void dtlst object source, DataListCommandEventArgs e)
{
}
but why are you attempting to inject a button?
Why not just include the button in the markup in the first place? I can't really see the need or reason to layout a datalist, and THEN decide to use code?
Just drag + drop in a button into the datalist, and you are quite much done.
So here is our datalist - we dropped in a plane jane button.
<asp:DataList ID="DataList1" runat="server" DataKeyField="ID" >
<ItemTemplate>
<div style="border-style:solid;color:black;width:300px;margin-left:25px">
<div id="mybox" runat="server" style="padding:5px;text-align:right">
<p>Hotel Name: <asp:TextBox ID="HotelName" runat="server" Text ='<%# Eval("HotelName") %>' /></p>
<p>First Name: <asp:TextBox ID="FirstName" runat="server" Text ='<%# Eval("FirstName") %>' /></p>
<p>Last Name: <asp:TextBox ID="LastName" runat="server" Text ='<%# Eval("LastName") %>' /></p>
<p>City: <asp:TextBox ID="City" runat="server" Text ='<%# Eval("City") %>' /></p>
<p>Province: <asp:TextBox ID="Province" runat="server" Text ='<%# Eval("Province") %>' /></p>
Active: <asp:CheckBox ID="Active" runat="server" Checked = '<%# Eval("Active") %>'/>
<br />
<asp:Button ID="cmdRow" runat="server" Text="Row click This item"
/>
</div>
</div>
<div style="height:15px"></div>
</ItemTemplate>
</asp:DataList>
And our code to fill looks like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
MyLoadData();
}
void MyLoadData()
{
using (SqlConnection con = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT TOP 3 * FROM tblHotels ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, con))
{
con.Open();
DataList1.DataSource = cmdSQL.ExecuteReader();
DataList1.DataBind();
}
}
And we now have this:
Now, lets wire up the button click, like this:
so, create new event in above (inteli-sense offers this choice).
protected void cmdRow_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
DataListItem gRow = (DataListItem)btn.Parent;
Debug.Print("Row index = " + gRow.ItemIndex.ToString());
int pkID = (int)(DataList1.DataKeys[gRow.ItemIndex]);
Debug.Print("Data base PK id = " + pkID.ToString());
Debug.Print("Hotel name = " + ((TextBox)(gRow.FindControl("HotelName"))).Text);
Debug.Print("City = " + ((TextBox)(gRow.FindControl("City"))).Text);
Debug.Print("--------------------");
}
And out output is this:
Row index = 1
Data base PK id = 72
Hotel name = Banff Rocky Mountain Resort
City = Banff
--------------------
so, it not at all clear why you want to spend the time, effort, and that of writing code when you can as a general rule just drop in a good old plane jane button from the designer right into the datalist, and then simple wire up a event.
Edit:
You can lead a horse to water - but can you get the horse to drink the water?
You can as noted inject a button, but I REALLY but REALLY but REALLY do not recommend doing this.
However, to get the button click event to work, then you can do this:
HtmlButton btn = new HtmlButton();
btn.InnerText = "Index " + e.Item.ItemIndex;
btn.Attributes.Add("onclick","__doPostBack('BtnTest2','')");
btn.ViewStateMode = ViewStateMode.Enabled;
HtmlGenericControl MyDiv = (HtmlGenericControl)e.Item.FindControl("mybox");
MyDiv.Controls.Add(btn);
Edit2:
Ok, there seems to be a issue of persistence.
So, adding MUST occur on page load (or could be earlier).
And the buttons have to be re-inserted each time on post-backs.
This now works:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MyLoadData();
}
AddBtns();
}
void MyLoadData()
{
using (SqlConnection con = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT TOP 3 * FROM tblHotels ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, con))
{
con.Open();
DataList1.DataSource = cmdSQL.ExecuteReader();
DataList1.DataBind();
}
}
}
void AddBtns()
{
foreach (DataListItem gRow in DataList1.Items)
{
Button btn = new Button();
btn.Text = "Index " + gRow.ItemIndex;
btn.ID = "Btn" + gRow.ItemIndex;
btn.Click += new EventHandler(BtnTest3);
HtmlGenericControl MyDiv = (HtmlGenericControl)gRow.FindControl("mybox");
MyDiv.Controls.Add(btn);
}
}
void BtnTest3(object sender, EventArgs e)
{
Debug.Print("buttn3 click");
}
Note two changes:
We don't add/inject the buttons ONLY on !IsPostback.
We inject the buttons each time on page load
We did not use the Item bound event.
I am trying to figure it out how can I display a dropDownList on a specific cell in the table right after clicking a button "Show DropDownlist" located on that cell.
This is the behind code , right now it is displaying the dropDownList at the last cell of each row. and I want to make it appear only when a button is clicked.
while (rdr.Read())
{
TableRow tRow = new TableRow();
myTable.Rows.Add(tRow);
for (int i = 0; i <= 4; i++)
{
// Create a new cell and add it to the row.
TableCell tCell = new TableCell();
if (i == 4)
{
tCell.Controls.Add(SM_List()); //Adding the dropdownlist
tRow.Cells.Add(tCell);
continue;
}
tCell.Text = rdr.GetString(i);
tCell.Attributes.Add("onmouseover", "this.style.cursor = 'pointer'; this.style.backgroundImage = ''; ");
tCell.Attributes.Add("onClick", "getData()");
tRow.Cells.Add(tCell);
}
/* iterate once per row */
}
I want to add this code, so it will be a button at first , instead of a drop down list :
Button bt = new Button();
bt.Text = "Switch";
bt.Click += new EventHandler(DropDownList_Show);
tCell.Controls.Add(bt);
But I am not sure how to display the DropDownList at the exact cell the button was located. and also I want to do some actions when Value was selected in the dropdownlist.
Can you please assist , I feel a little bit lost.
You can solve this issue easily by using GridView in ASP.NET.
Let say the GridView is declared as following in ASPX page.
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Id" />
<asp:BoundField DataField="Token" />
<asp:BoundField DataField="Secret" />
<asp:ButtonField CommandName="ShowDropDown" Text="Show" />
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList ID="dropDownList" runat="server" Visible="false">
<asp:ListItem Text="Valid" Value ="1"></asp:ListItem>
<asp:ListItem Text="Invalie" Value ="2"></asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Following is the method in code behind which populates the GridView.
private void BindGridView()
{
var tokens = new List<AccessToken>();
using (var conn = new SqlConnection("Server=somedbserver;Database=somedatabase;User Id=someuser;Password=somepassword;"))
{
using (var command = new SqlCommand())
{
command.Connection = conn;
command.CommandText = "SELECT Id, Token, Secret FROM Tokens";
command.CommandType = System.Data.CommandType.Text;
conn.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var token = new AccessToken();
token.Id = reader.GetInt32(0);
token.Token = reader.GetString(1);
token.Secret = reader.GetString(2);
tokens.Add(token);
}
}
}
}
GridView1.DataSource = tokens;
GridView1.DataBind();
}
And I am calling this method in Page_Load.
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
BindGridView();
}
}
Following is the event handler of RowCommand event of GridView which will display the dropdown list in the column next to the button which is clicked.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName == "ShowDropDown")
{
var row = GridView1.Rows[Convert.ToInt32(e.CommandArgument)];
//Using Cell[4] coz the Dropdownlist is in 5th column of the row.
//You need to replace 4 with appropriate column index here.
//Also replace "dropDownList" with the ID assigned to the dropdown list in ASPX.
var ddl = (DropDownList)row.Cells[4].FindControl("dropDownList");
if(ddl != null)
{
ddl.Visible = true;
}
}
}
You will able resolve your issue if you follow this approach.
Hey I make one more question with my full code because I am really stuck in this point.
When page loads a panel is filled with Book Categories taken from a database. This Categories are linkbuttons too. When I click one category a table is created below with all books on that category.
In that table the first cell is filled with Book's Title that is Linkbutton too.
I just want when I click i that Book'S Title linkbutton to fire the book_Details functions
so that the page now will show only the book I chose.
Instead of that whenever I click books'title linkbutton page loads again from 0.
The markup is:
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<div style="position: relative; top: 5%; left: 5%;">
<asp:Panel ID="MyPanel" runat="server"></asp:Panel>
</div>
<asp:MultiView ID="MultiView2" runat="server">
<asp:View ID="View1" runat="server">
<div style="overflow: auto; height: 400px;">
<asp:Table ID="ProductTBL" runat="server" BorderColor="Black" BorderStyle="Double" CellPadding="5" CellSpacing="5" BorderWidth="1px">
</asp:Table>
</div>
</asp:View>
<asp:View ID="View2" runat="server">
<asp:Table ID="detail_TBL" runat="server" BorderColor="Black" BorderStyle="Double" CellPadding="5" CellSpacing="5" BorderWidth="1px"></asp:Table>
</asp:View>
</asp:MultiView>
</asp:Content>
And the code-behind is:
protected void Page_Load(object sender, EventArgs e)
{
String conString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source =" +
Server.MapPath("~/e-bookstoredb.accdb");
using (OleDbConnection connection = new OleDbConnection(conString))
{
connection.Open();
ыtring query = "SELECT * FROM category";
using (OleDbCommand cmd = new OleDbCommand(query, connection))
{
OleDbDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
string literal = (string)reader["Name"];
LinkButton lnk_button = new LinkButton();
lnk_button.Text = literal;
lnk_button.ID = "cat_B" + reader["ID"].ToString();
lnk_button.CommandArgument = reader["ID"].ToString();
lnk_button.CommandName = reader["ID"].ToString();
lnk_button.Command += new CommandEventHandler(books_Show);
MyPanel.Controls.Add(lnk_button);
MyPanel.Controls.Add(new LiteralControl("</br>"));
}
reader.Close();
}
connection.Close();
}
}
protected void books_Show(object sender, EventArgs e)
{
LinkButton lnk = sender as LinkButton;
string cat = lnk.CommandArgument;
MultiView2.ActiveViewIndex = 0;
string ConStr = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source =" + Server.MapPath("~/e-bookstoredb.accdb");
using (OleDbConnection con = new OleDbConnection(ConStr))
{
con.Open();
string query = "SELECT * FROM product WHERE category = #cat";
using (OleDbCommand cmd = new OleDbCommand(query, con))
{
cmd.Parameters.AddWithValue("#cat", cat);
OleDbDataReader reader = cmd.ExecuteReader();
TableCell cell;
TableRow row = new TableRow();
TableCell titleCell = new TableCell();
titleCell.Text = "Τίτλος";
TableCell desCell = new TableCell();
desCell.Text = "Περιγραφή";
TableCell priceCell = new TableCell();
priceCell.Text = "Τιμή";
row.Cells.Add(titleCell);
row.Cells.Add(desCell);
row.Cells.Add(priceCell);
ProductTBL.Rows.Add(row);
LinkButton book_button;
while (reader.Read())
{
book_button = new LinkButton();
book_button.ID = "book" + reader["ID"].ToString();
book_button.Text = (string)reader["Title"];
book_button.CommandArgument = (string) reader["Title"];
book_button.CommandName = "cmd" + reader["ID"].ToString();
book_button.Command += new CommandEventHandler(book_Details);
row = new TableRow();
cell = new TableCell();
cell.Controls.Add(book_button);
row.Cells.Add(cell);
cell = new TableCell();
cell.Text = (string)reader["Description"];
row.Cells.Add(cell);
cell = new TableCell();
cell.Text = reader["price"].ToString()+"€";
row.Cells.Add(cell);
ProductTBL.Rows.Add(row);
}
reader.Close();
}
con.Close();
}
}
protected void book_Details(object sender, EventArgs e)
{
MultiView2.ActiveViewIndex = 1;
LinkButton lnk = sender as LinkButton;
String bookTitle = lnk.CommandArgument;
//...And then I just create a table to show only the book user selected
//...this table gets filled buy this query = " SELECT * FROM product WHERE Title=#bookTitle
}
You must wrap your code within Page_Load with if(!IsPostBack) as shown below. This is because according to ASP.Net page lifecycle Page_Load fires first and control events firs after that.
So, whenever you click your LinkButtons the server first calls the Page_Load and then it calls LinkButton's click event.
So, it's a good idea to wrap your Page_Load code where you only wants to execute once during Page_Load like this.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Your Page_Load logic goes here
}
}
According to MSDN the definition for IsPostBack is
Gets a value that indicates whether the page is being rendered for the
first time or is being loaded in response to a postback.
true if the page is being loaded in response to a client postback;
otherwise, false.
Hope this helped!
I want add control label in my gridview, is it possible add with datatable?
here my code:
<asp:GridView ID="reportScheduleDetailsGridView"
runat="server"
AutoGenerateColumns="False">
</asp:GridView>
I try use tag html span, but it not render:
string queryString = #"SELECT * FROM [table1]";
SqlCommand cmd = new SqlCommand(queryString, connOkto);
using (SqlDataReader sdrMaster = cmd.ExecuteReader())
{
while (sdrMaster.Read())
{
DataRow rows = dataTable.NewRow();
rows[0] = sdrMaster["name"].ToString();
for (var x = 1; x < maxCol; x++)
{
queryString = #"SELECT * FROM table2";
cmd = new SqlCommand(queryString, connOkto);
using (SqlDataReader sdrRev = cmd.ExecuteReader())
{
while (sdrRev.Read())
{
blok = "<span></span>";
no = (int)Int16.Parse(sdrRev["no"].ToString());
}
}
rows[x] = blok;
if (no > 1)
{
no--;
}
else
{
blok = "";
}
}
dataTable.Rows.Add(rows);
} }
I don't know, how can add control asp in gridview, like label.
Please help, thanks.
One way to add controls is using OnRowDataBound event of GridView. Add a placeHolder to say, inside <ItemTemplate> of your grid view.
<asp:GridView ID="EmpGridView" OnRowDataBound="EmpGridView_RowDataBound"
<ItemTemplate>
<asp:PlaceHolder ID="placeholder1" runat="server"></asp:PlaceHolder>
</ItemTemplate>
...></asp:GridView>
Ang your code behind file will have:
protected void EmpGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Create a label control
Label lbl = new Label();
lbl.Text="MyDynamic Label";
lbl.ID="lbl1"; // use ID values you prefer
// lets create one more control for example
LinkButton btnlink = new LinkButton();
btnlink.Text = "Delete";
btnlink.ID = "btnDelete";
linkb.Click += new EventHandler(btnlink_Click);
// add the controls to your placeholder inside <ItemTemplate>
PlaceHolder phld = e.Row.FindControl("Placeholder1") as PlaceHolder;
phld.Controls.Add(btnlink);
phld.Controls.Add(lbl);
//code to add the control to only a specific COLUMN/ Cell
e.Row.Cells[1].Controls.Add(btnlink); // adding to 2nd Column
// adding to last column..
e.Row.Cells[EmpGridView.Columns.Count - 1].Controls.Add(btnlink);
}
}
Hope this various ways of adding controls to Templates as well as in a cell of GridView helps you.
I am creating an asp.net / C# application with 2 pages.
The JavaScript on 1stPage.aspx will pass two parameters to the second page:
2ndPage.aspx?Paramter1=abc&Paramter2=xyz
2ndPage.aspx will fire a query to a SQL database and dynamically create a gridview.
I create 5 different gridviews on the same page dynamically with different IDs.
I want to pagenate gridview.
When I try to paginate, there is no change on the last 4 grids. Only pagination of first gridview is works properly.
I have tried to cache the dataview, but nothing seems to work.
C# CODE:
protected void Page_Load(Object Src, EventArgs E)
{
if (!IsPostBack)
{
string Param1= Page.Request.QueryString["Paramter1"];
string Param1 = Page.Request.QueryString["Paramter2"];
SqlDataAdapter cmdldata = new SqlDataAdapter("" + Param1 + " " + Param1, sqlconn);
DataView dataview_ldata;
GridView gv = new GridView();
ph.Controls.Add(gv);
gv.ID = "grid" + param1;
gv.AutoGenerateColumns = true;
gv.ShowFooter = false;
gv.CellPadding = 2;
gv.CellSpacing = 0;
gv.Font.Size = 11;
gv.EnableViewState = true;
gv.AllowPaging = true;
gv.PageSize = 10;
gv.RowStyle.Wrap = false;
gv.HeaderStyle.Wrap = false;
gv.PageIndexChanging += new GridViewPageEventHandler(gv_PageIndexChanging);
DataSet dsldata;
dsldata = new DataSet();
cmdldata.Fill(dsldata);
dataview_ldata = dsldata.Tables[0].DefaultView;
gv.DataSource = dataview_ldata;
gv.DataBind();
Cache["data"] = dataview_ldata;
ph.DataBind();
}//end of if IsPostBack
}//end of pageload
void gv_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView gv = (GridView)sender;
gv.PageIndex = e.NewPageIndex;
gv.DataSource = (DataView)Cache["data"];
gv.DataBind();
}
HTML CODE:
<form id="form1" runat="server">
<div>
<asp:PlaceHolder id="ph" runat="server" />
</div>
</form>