Hello all I'm working on a little project where I'm adding controls to a page based on a SQL table of questions, this table will grow overtime. I just wanted to share the code and see if there was any better way or if any of the experts could chime in and give me any insight on future problems. Here is the code:
protected void Page_Load(object sender, EventArgs e)
{
try
{
SqlParameter[] paramz = new SqlParameter[1];
paramz[0] = new SqlParameter("#c_id", 1);
dt = SqlHelper.ExecuteDataTable(ConfigurationManager.ConnectionStrings["sql"].ToString(), CommandType.StoredProcedure, "get_Questions", paramz);
clinicName.Text = "<b>" + dt.Rows[0]["Clinic Name"].ToString();
for(int row = 0; row <= dt.Rows.Count; row++)
{
if (row == dt.Rows.Count) //if we're on the last question put a break for spacing(this could be fixed with styling)
{
Literal alit = new Literal();
alit.Text = "<br/>";
questionsPanel.Controls.Add(alit);
}
else
{
addQuestion(dt.Rows[row], row);
}
}
}
catch (Exception err)
{
Response.Write(err.Message);
}
}
private void addQuestion(DataRow row, int i)
{
Label lbl = new Label();
lbl.Text = row["question"].ToString();
questionsPanel.Controls.Add(lbl);
Literal lit = new Literal();
lit.Text = "<br/>";
questionsPanel.Controls.Add(lit);
TextBox txt = new TextBox();
txt.ID = "txt" + i.ToString();
questionsPanel.Controls.Add(txt);
Literal lit2 = new Literal();
lit2.Text = "<br/>";
questionsPanel.Controls.Add(lit2);
}
Use a Repeater control:
ASPX Code:
<asp:Repeater id="repData" runat="server">
<ItemTemplate>
<asp:Label id="lblQuestion" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "question") %>' />
<br />
<asp:TextBox id="lblAnswer" runat="server" />
</ItemTemplate>
<FooterTemplate>
<br />
</FooterTemplate>
</asp:Repeater>
Code behind:
// Populate repeater
SqlParameter[] paramz = new SqlParameter[1];
paramz[0] = new SqlParameter("#c_id", 1);
dt = SqlHelper.ExecuteDataTable(ConfigurationManager.ConnectionStrings["sql"].ToString(), CommandType.StoredProcedure, "get_Questions", paramz);
repData.DataSource = dt;
repData.DataBind();
If the controls either use or contribute to ViewState, then you must ensure that the same controls are added to ViewState in the same order, on every post back. The order in which objects are added to ViewState depends on the order of the controls in the control tree.
Related
here I wanna add a dynamic dropdowns as a table in a html document, and I want to bind that dropdown with values of my SQLSERVER table column. once I finally choose the values in dropdown want to retrieve those selected values/text back to ma SqlServer.
please help me to finish this,
I also post ma codebehind with this question..
protected void txtcreate_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
DropDownList dl = new DropDownList();
int roomno = Convert.ToInt16(txtroom.Text);
int panno = Convert.ToInt16(txtpan.Text);
StringBuilder str = new StringBuilder();
str.Append("<table>");
for(int row = 0; row < roomno; row++)
{ str.Append("<tr>");
for(int col = 0; col < panno; col++)
{
dt = new DataTable();
str.Append("<td>");
dl.ID = "dd" + row.ToString() + col.ToString();
dt = sp.showStudent();
dl.DataSource = dt;
dl.DataTextField = "name";
dl.DataBind();
str.Append(dl);
str.Append("</td>");
ph.Controls.Add(dl);
}
str.Append("</tr>");
}
str.Append("</table>");
ltr.Text = str.ToString();
}
}
and the aspx file is
<form id="form1" runat="server">
<asp:TextBox ID="txtroom" runat="server"></asp:TextBox><asp:TextBox ID="txtpan" runat="server"></asp:TextBox><asp:Button ID="txtcreate" runat="server" OnClick="txtcreate_Click" Text="Button" />
<center>
<div>
<asp:GridView ID="grid" AutoGenerateColumns="true" runat="server">
</asp:GridView>
</div>
<asp:PlaceHolder ID="ph" runat="server">
<asp:Literal ID="ltr" runat="server"></asp:Literal>
</asp:PlaceHolder>
</center>
</form>
thanks guys...
I dynamically create my labels and Radio Button Lists in my web forms asp.net application. Afterwards, I place them in a table.
I am having a problem with displaying the actual radio button list control in the table.
How do I display the control instead of the Text being shown?
The code I have is:
string cs = ConfigurationManager.ConnectionStrings["OnlineCheckListConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
DataTable dt = new DataTable();
using (SqlDataAdapter sda = new SqlDataAdapter("spGetApplications", con))
{
sda.SelectCommand.CommandType = CommandType.StoredProcedure;
sda.SelectCommand.Parameters.AddWithValue("#uname", "rbrown");
sda.Fill(dt);
}
if (dt.Rows.Count > 0)
{
string tablestring = "<table border = \"1\" CssClass=\"TestClass\">" +
"<tr><td>First Column Heading</td><td>second Column</td></tr>";
for (int i = 0; i < dt.Rows.Count; i++)
{
Label lbl = new Label();
RadioButtonList c = new RadioButtonList();
lbl.ID = "Label" + i.ToString();
c.ID = "cbl" + i.ToString();
lbl.Text += dt.Rows[i][1].ToString() + "<br/>";
c.Items.Add(new ListItem("Yes"));
c.Items.Add(new ListItem("NO"));
c.RepeatDirection = RepeatDirection.Horizontal;
//this.Controls.Add(lbl);
//this.Form.Controls.Add(c);
tablestring = tablestring + "<tr><td>" + lbl.Text.ToString() + "</td><td>" + c + "</td></tr>";
}
divTable.InnerHtml = tablestring;
I Suggest you to use AspGridView, not plain HTML table.
You could use <ItemTemplate> and <EditItemTemplate> to add RadioButtonList in aspx.
<asp:GridView ID="gvOrders" DataKeyNames="OrderId" runat="server" AutoGenerateColumns="false"
OnRowEditing="EditCustomer" OnRowDataBound="RowDataBound" OnRowUpdating="UpdateCustomer"
CssClass="Grid" OnRowCancelingEdit="CancelEdit">
<Columns>
<asp:BoundField DataField="ContactName" HeaderText="Customer Name" ReadOnly="true" />
<asp:BoundField DataField="ShipCity" HeaderText="Ship City" ReadOnly="true" />
<asp:TemplateField HeaderText="Shipper">
<ItemTemplate>
<asp:Label ID="lblShipper" runat="server" Text='<%# Eval("CompanyName")%>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:Label ID="lblShipper" runat="server" Text='<%# Eval("ShipperId")%>' Visible="false"></asp:Label>
<asp:RadioButtonList ID="rblShippers" runat="server">
</asp:RadioButtonList>
</EditItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="True" />
</Columns>
</asp:GridView>
Then fill the data through RowDataBound
protected void RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && gvOrders.EditIndex == e.Row.RowIndex)
{
RadioButtonList rblShippers = (RadioButtonList)e.Row.FindControl("rblShippers");
string query = "SELECT * FROM Shippers";
SqlCommand cmd = new SqlCommand(query);
rblShippers.DataSource = GetData(cmd);
rblShippers.DataTextField = "CompanyName";
rblShippers.DataValueField = "ShipperId";
rblShippers.DataBind();
rblShippers.Items.FindByValue((e.Row.FindControl("lblShipper") as Label).Text).Selected = true;
}
}
Here is the demo:
https://www.aspsnippets.com/demos/406/default.aspx
And Complete Example:
https://www.aspsnippets.com/Articles/Populate-and-save-ASPNet-RadioButtonList-with-Selected-Value-in-Edit-ItemTemplate-of-GridView.aspx
The RadioButtonList is a WebControl, that can be used inside another WebControl. In your code you are creating a table by concatenating HTML text, therefore, outside the domain of the Web Forms view state model.
When you are concatenating c in your HTML text variable, you are just getting the value returned by c.ToString(), which by default is the full name of the type.
Having said that, please use the System.Web.UI.WebControls.Table type to build your table instead, and add the System.Web.UI.WebControls.RadioButtonList to it; I'm leaving a basic example below that you can use as a starting point:
In your aspx file (somewhere inside your form element):
<asp:Table runat="server" ID="myTable"></asp:Table>
In your code-behind file:
using System.Web.UI.WebControls;
...
void SomeMethod()
{
var row = new TableRow();
var cell = new TableCell();
var radioButtonList = new RadioButtonList();
radioButtonList.Items.Add(new ListItem("Yes"));
radioButtonList.Items.Add(new ListItem("NO"));
cell.Controls.Add(radioButtonList);
row.Cells.Add(cell);
myTable.Rows.Add(row);
}
I have created gridview. Added a textbox to specify what number of columns user want to add to the grid dynamically and its done successfully.
I want to add text box to the dynamically added fields to enter the data and save it to the database(I am able to add text fields to the rows and save data) but i didnt got any solution yet.
I have tried with itemplate but I don't know much about it. i have added my code below.
Here is my aspx code
<input type="hidden" runat="server" value="0" id="columnAdded"/>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<%--<asp:CommandField ShowEditButton="True" />--%>
<asp:TemplateField HeaderText="S. No.">
<ItemTemplate>
<asp:Label ID="lblsno" runat="server" Text='<%#Container.DataItemIndex+1 %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:LinkButton ID="lbInsert" runat="server">Insert</asp:LinkButton>
</FooterTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Parts" DataField="parts">
</asp:BoundField>
<%--<asp:TemplateField>
<ItemTemplate>
<asp:PlaceHolder ID="PlaceHolder_InputControl" runat="server" ></asp:PlaceHolder>
</ItemTemplate>
</asp:TemplateField>--%>
<%--<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnedit" runat="server" Text="Edit" CommandName="EditRow"/>
</ItemTemplate>
</asp:TemplateField>--%>
</Columns>
</asp:GridView>
and here is .cs
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
try
{
drpstation.Items.Clear();
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select * from stationdesc where stndesc <> '' and id is not null";
cmd.ExecuteNonQuery();
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds, "stationdesc");
drpstation.DataSource = ds.Tables[0];
drpstation.DataTextField = ds.Tables[0].Columns["stndesc"].ColumnName.ToString();
drpstation.DataValueField = ds.Tables[0].Columns["id"].ColumnName.ToString();
drpstation.DataBind();
drpstation.Items.Insert(0, new ListItem("Select Station", "0"));
}
catch (Exception ex)
{
string Msg = "select station error";
Msg += ex.Message;
}
finally
{
con.Close();
}
}
if (!IsPostBack)
{
griddisplay();
}
}
public void griddisplay()
{
try
{
con.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM stnparts", con);
SqlDataReader dr = cmd.ExecuteReader();
GridView1.DataSource = dr;
GridView1.DataBind();
//DataTable dt = new DataTable();
//dt.Columns.Add("Parts", typeof(string));
//DataRow drr = dt.NewRow();
//drr["Parts"] = "Weldmet";
//dt.Rows.Add(drr);
//drr = dt.NewRow();
//drr["Parts"] = "MFG Parts";
//dt.Rows.Add(drr);
//GridView1.DataSource = dt;
//GridView1.DataBind();
}
catch (Exception d)
{
string message = "grid error";
message += d.Message;
}
finally
{
con.Close();
}
}
protected void btnadd_Click(object sender, EventArgs e)
{
int num;
num = Convert.ToInt32(txtnumber.Text.Trim());
int addedColumn = Convert.ToInt32(columnAdded.Value);
for (int i = addedColumn + 1; i <= addedColumn + num; i++)
{
string name = "Unit";
name = string.Concat(name, i);
TemplateField test = new TemplateField();
test.HeaderText = name;
GridView1.Columns.Add(test);
TextBox txtname = new TextBox();
string txtunit = "txtunit";
txtname.ID = txtunit + i;
}
griddisplay();
columnAdded.Value = (addedColumn + num).ToString();
}
public class TemplateHandler : ITemplate
{
void ITemplate.InstantiateIn(Control container)
{
TextBox txtbox = new TextBox();
txtbox.Text = "test";
txtbox.DataBinding += Txtbox_Binding;
container.Controls.Add(txtbox);
}
private void Txtbox_Binding(object sender, EventArgs e)
{
//throw new NotImplementedException();
TextBox txttest = (TextBox)sender;
GridViewRow container = (GridViewRow)txttest.NamingContainer;
//txttest.Text = ((TableNameClass)container.DataItem).SkillText;
((DataRowView)container.DataItem)["SkillText"].ToString();
}
}
Please help
Just a pseudo/sample code(not tested!) based on the code you posted, to give you some heads-up
protected void btnadd_Click(object sender, EventArgs e)
{
int num;
num = Convert.ToInt32(txtnumber.Text.Trim());
int addedColumn = Convert.ToInt32(columnAdded.Value);
for (int i = addedColumn + 1; i <= addedColumn + num; i++)
{
string name = "Unit";
name = string.Concat(name, i);
TemplateField test = new TemplateField();
test.HeaderText = name;
test.ItemTemplate = new TemplateHandler (); // ** This line to set ItemTemplate is missing in the code you posted
GridView1.Columns.Add(test);
// ... Other code as you need
}
}
Hope this help you.
I have a DropDownList bounded with list of items from SqlDataSource. With the help of DropDownList_SelectedIndexchanged() function i am able to generate two dynamic text boxes.
Required Output: I need to search for the data based on the textbox inputs given by the user and Searched data shall be displayed in JQGrid with the help of Button_Click() event.
Current Issue: The textbox inputs are not retrieved and it always retrieved as null string "".
Exception obtained is : Incorrect Syntax near "AND" (SQL Query)
How to solve this issue?
My aspx code:
<asp:Panel ID="Panel5" runat="server" Height="221px">
<span style="font-size: 135%; font-family: Verdana; font-weight: bold"> Search Functionalities </span>
<asp:DropDownList ID="DropDownList5" runat="server" DataSourceID="column_list_for_filter" DataTextField="All_Columns" DataValueField="All_Columns" OnSelectedIndexChanged ="DropDownList5_SelectedIndexChanged" AutoPostBack="true">
</asp:DropDownList>
<asp:SqlDataSource ID="column_list_for_filter" runat="server" ConnectionString="<%$ ConnectionStrings:DatabaseConnectionString %>" SelectCommand="SELECT COLUMN_NAME 'All_Columns' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='RESULT' "></asp:SqlDataSource>
<asp:Button ID="Button1" runat="server" Font-Bold="True" Font-Names="Arial" Font-Size="Small" OnClick="Button1_Click" Text="Search Flow Periods" Width="144px" />
<asp:Table ID="dynamic_filter_table" runat="server" ToolTip="Results">
</asp:Table>
</asp:Panel>
My C# code:
//Creation of Two Dynamic Text Box Web Controls on DDL selection
protected void DropDownList5_SelectedIndexChanged(object sender, EventArgs e)
{
createdynamiccontrols();
}
/*Two Text Boxes and Two Labels for input and search the FlowPeriod and display in JqGrid
thru button click event*/
protected void createdynamiccontrols()//(string ID1, string ID2)
{
int i = DropDownList5.SelectedIndex;
++i;
TableRow row;
row = new TableRow();
TableCell cell1 ;
cell1 = new TableCell();
TableCell cell2;
cell2= new TableCell();
// Set a unique ID for each TextBox added
TextBox tb1;
tb1 = new TextBox();
TextBox tb2;
tb2 = new TextBox();
Label lbl1;
lbl1 = new Label();
Label lbl2;
lbl2 = new Label();
// Set a unique ID for each TextBox added
tb1.ID = "lowerbound_" + i.ToString();
tb2.ID = "upperbound_"+ i.ToString() ;
lbl1.Text = "LowerBound:";
lbl1.Font.Size = FontUnit.Point(10);
lbl1.Font.Bold = true;
lbl1.Font.Name = "Arial";
lbl2.Text = "UpperBound:";
lbl2.Font.Size = FontUnit.Point(10);
lbl2.Font.Bold = true;
lbl2.Font.Name = "Arial";
// Add the control to the TableCell
cell1.Controls.Add(lbl1);
cell1.Controls.Add(tb1);
cell2.Controls.Add(lbl2);
cell2.Controls.Add(tb2);
// Add the TableCell to the TableRow
row.Cells.Add(cell1);
row.Cells.Add(cell2);
dynamic_filter_table.Rows.Add(row);
dynamic_filter_table.EnableViewState = true;
ViewState["dynamic_filter_table"] = true;
Button1.EnableViewState = true;
ViewState["Button_1"] = true;
}
protected override object SaveViewState()
{
object[] viewstate = new object[2];
List<string> dynamic_text_values = new List<string>();
foreach (TableRow row in dynamic_filter_table.Controls)
{
foreach (TableCell cell in row.Controls)
{
if (cell.Controls[1] is TextBox)
{
dynamic_text_values.Add(((TextBox)cell.Controls[1]).Text);
}
}
}
viewstate[0] = dynamic_text_values.ToArray();
viewstate[1] = base.SaveViewState();
return viewstate;
}
protected override void LoadViewState(object savedState)
{
if (savedState is object[] && ((object[])savedState).Length == 2 && ((object[])savedState)[0] is string[])
{
object[] newViewState = (object[])savedState;
string[] txtValues = (string[])(newViewState[0]);
if (txtValues.Length > 0)
{
createdynamiccontrols();
}
base.LoadViewState(newViewState[1]);
}
else
{
base.LoadViewState(savedState);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
createdynamiccontrols();
int j = DropDownList5.SelectedIndex;
++j;
Panel6.Visible = true;
JQGrid9.Visible = true;
TextBox lowerboundd = dynamic_filter_table.FindControl("lowerbound_" + j.ToString()) as TextBox;
TextBox upperbound = dynamic_filter_table.FindControl("upperbound_" + j.ToString()) as TextBox;
string testt = lowerboundd.Text;
con.Open();
SqlDataAdapter da = new SqlDataAdapter("SELECT ColumnName1,Columnname2 FROM RESULT WHERE " + DropDownList5.SelectedValue + " >= " + lowerboundd.Text + " AND " + DropDownList5.SelectedValue + " <= " + upperbound.Text, con);
DataSet ds = new DataSet();
da.Fill(ds);
/*Error occurs here as Incorrect Syntax near AND as the string obtained is "" and not
textbox inputs*/
con.Close();
Session["DataforSearch"] = ds.Tables[0];
}
protected void Page_Load(object sender, EventArgs e)
{
//Dynamic controls creation on Page Load
if (!IsPostBack)
{
BindDropDownLists();
}
dynamic_filter_table.EnableViewState = true;
}
You need to move BindDropDownLists(); to the Page_Init method from Page_Load or else the page lifecycle will not find the viewstate and attach to your controls. By the time you are in Page_Load you are too late. Make sure your logic to create the controls in init and your logic to retrieve the data in load/events and you should see some results.
You don't need the viewstate stuff as that will automagically wire itself up, you can't create the dynamic controls in a control event like click or selectedindexchanged as thats too late in the lifecycle. The dynamic controls need to be created before load for the viewstate to be wired by the time load comes around.
More Reading
This is very interesting..
I want to have multiple gridviews in a panel. and the number of gridviews is not fixed..
So basically i think there should be no code in the .aspx page as i have to create the gridview in codebehind.
I have the code for 1 gridview in one panel.. where i define the grid view in the HTML page and populate it from the code behind.
Here is the code for that.. can any 1 please help me with the multiple gridviews...
this is on the .aspx page
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
AllowSorting="True" CellSpacing="2" onsorting="GridView1_Sorting"
Width="100%" ForeColor="White" GridLines="None"
ondatabound="GridView1_DataBound1">
<Columns>
<EditItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("PolicyID") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("PolicyID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
this is the code behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DataTable dt = new DataTable();
SqlConnection connection = new SqlConnection(Session["ConnectionStringSQL"].ToString());
connection.Open();
SqlCommand sqlCmd = new SqlCommand("SELECT Policies.PolicyID, FROM Policies", connection);
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCmd);
sqlDa.Fill(dt);
connection.Close();
if (dt.Rows.Count > 0)
{
for (int j = 0; j < dt.Rows.Count; j++)
{
policyID.Add(dt.Rows[j]["PolicyID"].ToString());
}
taskTable.Columns.Add("PolicyID");
if (policyID.Count != 0)
{
for (int k = 0; k < policyID.Count; k++)
{
DataRow tableRow = taskTable.NewRow();
tableRow["PolicyID"] = policyID[k];
taskTable.Rows.Add(tableRow);
}
Session["TaskTable"] = taskTable;
GridView1.DataSource = Session["TaskTable"];
GridView1.DataBind();
}
}
}
}
Answer 1 works but just be careful if you are nesting this inside a master page, etc.. because it seems when you just bind directly to the PAGE you cant expect it to actually be placed inside your form tag.
I have a sproc that returns unknown number of different tables that i want dumped to the page so i put a Placeholder on the aspx page
and then used the loop thru my dataset
foreach (DataTable table in ds.Tables)
{
GridView gv = new GridView();
gv.DataSource = table;
gvPlaceHolder.Controls.Add(gv);
}
.....OR ....
for (int i = 0; i < ds.Tables.Count; i++)
{
GridView gv = new GridView();
gv.DataSource = ds.Tables[i];
gvPlaceHolder.Controls.Add(gv);
}
.. and then bind to the placeholder so the tables end up inside my form within my child page, that is inside my master page
gvPlaceHolder.DataBind();
Not tested, but this kind of thing should do it:
for (int i=0;i<5;i++) {
GridView gv = new GridView();
gv.DataSource = datasources[i];
Page.Controls.Add(gv);
}
Page.DataBind();
DataSet ds = new DataSet();
ds = obj.GetMedicalGridWithAge(MphID, ProductCode);
if(ds.Tables.Count > 0)
{
if (ds.Tables[1].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables.Count; i++)
{
GridView gv = new GridView();
gv.ID = "gv" + (i + 1);
gv.DataSource = ds.Tables[i];
gv.DataBind();
Panel1.Controls.Add(gv);
Label newLine = new Label(); newLine.Text = "<br/>";
Panel1.Controls.Add(newLine);
}
}
else
{
GridView gv = new GridView();
gv.ID = "gv" ;
gv.DataSource = null;`
gv.DataBind();
Panel1.Controls.Add(gv);
}
}