I have a form with a table, a cancel button and a save button. The last column in the table is editable. The save button saves the edits to the last column. The problem I am having is when I save, the table posts back as having 0 rows in the SaveButton_ServerClick method.
HTML:
<%# Page validateRequest="false" Language="C#" AutoEventWireup="true" CodeBehind="xxxxxx.aspx.cs" Inherits="xxxxx.xxx" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="Form1" runat="server">
<asp:Table id="SettingsTable" runat="server" EnableViewState="true"></asp:Table>
<asp:Button id="CancelButton" runat="server" Text="Cancel"></asp:Button>
<asp:Button id="SaveButton" runat="server" Text="Save"></asp:Button>
</form>
</body>
</html>
C#:
const string CONFIG_SET_ID = "ConfigurationSetId";
const string CONFIG_SET_NAME = "ConfigurationSetName";
const string CONFIG_SET_DESC = "ConfigurationSetDescription";
const string APP_NAME = "AppName";
const string APP_ID = "AppId";
const string SET_CAT = "SettingCategory";
const string SET_DESC = "SettingDescription";
const string SET_CAT_ID = "SettingCategoryId";
const string TITLE = "title";
const int CONFIG_SET_CELL = 0;
const int APP_NAME_CELL = 1;
const int SET_CAT_CELL = 2;
const int SETTINGKEY_CELL = 3;
const int SETTINGVALUE_CELL = 4;
static Dictionary<string, ConfigurationDictionary> _cfgDics = new Dictionary<string, ConfigurationDictionary>();
protected void Page_Load(object sender, EventArgs e)
{
AppCfg.AppName = "xxxxx";
AppCfg.Initialize();
if (!Page.IsPostBack)
LoadSettings();
SaveButton.Click += SaveButton_ServerClick;
CancelButton.Click += CancelButton_ServerClick;
}
/// ADDING THIS FIXED THE POSTBACK PROBLEM.
void CancelButton_ServerClick(object sender, EventArgs e)
{
LoadSettings();
}
void SaveButton_ServerClick(object sender, EventArgs e)
{
foreach (TableRow row in SettingsTable.Rows)
{
if (row.Cells[SETTINGVALUE_CELL].Controls[0].GetType().Equals(typeof(TextBox)))
{
string appId = row.Cells[APP_NAME_CELL].Attributes[APP_ID];
string settingKey = row.Cells[SETTINGKEY_CELL].Text;
string settingValue = ((TextBox)row.Cells[SETTINGVALUE_CELL].Controls[0]).Text;
if (_cfgDics.ContainsKey(appId) && _cfgDics[appId][settingKey].Value != settingValue)
_cfgDics[appId][settingKey] = settingValue;
}
}
System.Threading.Thread.Sleep(1000);
LoadSettings();
}
void CancelButton_ServerClick(object sender, EventArgs e)
{
LoadSettings();
}
private void LoadSettings()
{
//foreach (ConfigurationDictionary dic in _cfgDics.Values)
// dic.Dispose();
//_cfgDics.Clear();
SettingsTable.Rows.Clear();
// Build Settings table
// Build Header row
TableRow headerRow = new TableRow();
headerRow.Cells.Add(new TableCell() { Text = "Config Set" });
headerRow.Cells.Add(new TableCell() { Text = "Application" });
headerRow.Cells.Add(new TableCell() { Text = "Category" });
headerRow.Cells.Add(new TableCell() { Text = "Setting Key" });
headerRow.Cells.Add(new TableCell() { Text = "Setting Value" });
SettingsTable.Rows.Add(headerRow);
IniFileEditor xxxIni = new IniFileEditor();
string dbConnString = xxxIni.ReadValue(ConfigurationDictionary.SECKEY, ConfigurationDictionary.SETTING_DB_KEY);
if (!string.IsNullOrEmpty(dbConnString))
{
// Build each setting
using (DatabaseAccess dba = new DatabaseAccess(dbConnString))
using (SqlCommand cmd = new SqlCommand("Select * from AllSettings"))
using (SqlDataReader reader = dba.GetSqlReader(cmd))
{
while (reader.Read())
{
TableRow row = new TableRow();
string appId = string.Empty;
row.Cells.Add(new TableCell() { Text = reader[CONFIG_SET_NAME].ToString() });
row.Cells[CONFIG_SET_CELL].Attributes[CONFIG_SET_ID] = reader[CONFIG_SET_ID].ToString();
row.Cells[CONFIG_SET_CELL].Attributes[TITLE] = reader[CONFIG_SET_DESC].ToString();
row.Cells.Add(new TableCell() { Text = reader[APP_NAME].ToString() });
appId = reader[APP_ID].ToString();
row.Cells[APP_NAME_CELL].Attributes[APP_ID] = appId;
row.Cells[APP_NAME_CELL].Attributes[TITLE] = string.Format("AppId:\t{0} \r\nMachine:\t{1} \r\nIPAddress:\t{2}",
reader[APP_ID],
reader["MachineName"],
reader["MachineAddress"]);
row.Cells.Add(new TableCell() { Text = reader[SET_CAT].ToString() });
row.Cells[SET_CAT_CELL].Attributes[SET_CAT_ID] = reader[SET_CAT_ID].ToString();
row.Cells.Add(new TableCell() { Text = reader["SettingKey"].ToString() });
row.Cells[SETTINGKEY_CELL].Attributes[TITLE] = reader[SET_DESC].ToString();
TextBox valueTextbox = new TextBox();
valueTextbox.Text = reader["SettingValue"].ToString();
row.Cells.Add(new TableCell());
row.Cells[SETTINGVALUE_CELL].Controls.Add(valueTextbox);
if (!_cfgDics.ContainsKey(appId))
_cfgDics.Add(appId, new ConfigurationDictionary(appId));
SettingsTable.Rows.Add(row);
}
}
}
}
Try creating the dynamic controls every time in the PreInit event, that is the only way ViewState will ever get applied on Post-Back.
protected void Page_PreInit(object sender, EventArgs e)
{
LoadSettings();
}
Upon post back the table data been lost. so please keep the table data in the sessionstate or viewstate.
Related
I am working with dynamically created text fields. Most solutions I have found thus far have been related to retaining view state on postback, but I believe I have taken care of that issue. On postback, the values that are in the text fields are retained.
The issue I am having: I can't get the database values currently stored to load in the dynamic fields. I am currently calling loadUpdates() to try to do this, but unsure how to grab the data row, while also making sure I can continue to add new fields (or remove them). How can I achieve this?
"txtProjectsUpdate" is the text field, "hidFKID" is the foreign key to a parent table, and "hidUpdateID" is the hidden value of the primary key in the child table (the values I am attempting to load).
Markup:
<div>
<asp:Button ID="btnAddTextBox" runat="server" Text="Add" OnClick="btnAddTextBox_Click" />
<asp:Placeholder ID="placeHolderControls" runat="server"/>
</div>
<asp:TextBox runat = "server" ID = "hidUpdateID" />
<asp:HiddenField runat = "server" ID = "hidFKID" />
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
for (var i = 0; i < TextBoxCount; i++)
AddTextBox(i);
}
if (!IsPostBack)
{
DataTable dt = new DataTable();
dt = selectDetails();
tryHidFKID(hidFKID, dt.Rows[0]["fkprjNumber"].ToString());
loadUpdates();
}
}
protected void btnAddTextBox_Click(object sender, EventArgs e)
{
AddTextBox(TextBoxCount);
TextBoxCount++;
}
private int TextBoxCount
{
get
{
var count = ViewState["txtBoxCount"];
return (count == null) ? 0 : (int)count;
}
set { ViewState["txtBoxCount"] = value; }
}
private void btnRemove_Click(object sender, EventArgs e)
{
var btnRemove = sender as Button;
if (btnRemove == null) return;
btnRemove.Parent.Visible = false;
}
private void AddTextBox(int index)
{
var panel = new Panel();
panel.Controls.Add(new TextBox
{
ID = string.Concat("txtProjectUpdates", index),
Rows = 5,
Columns = 130,
TextMode = TextBoxMode.MultiLine,
CssClass = "form-control",
MaxLength = 500
});
panel.Controls.Add(new TextBox
{
ID = string.Concat("hidUpdateID", index)
});
var btn = new Button { Text = "Remove" };
btn.Click += btnRemove_Click;
panel.Controls.Add(btn);
placeHolderControls.Controls.Add(panel);
}
protected void loadUpdates()
{
DataTable dt = dbClass.ExecuteDataTable
(
"spSelectRecords", <db>, new SqlParameter[1]
{
new SqlParameter ("#vFKPrjNumber", hidFKID.Value)
}
);
AddTextBox(TextBoxCount);
TextBoxCount++;
}
protected void tryHidFKID(HiddenField hidFKID, string txtSelected)
{
try
{
hidFKID.Value = txtSelected;
}
catch
{
hidFKID.Value = "";
}
}
I've a gridview with webcontrols(Textbox,Button in footer). Dynamically I need to create any number of gridviews by the following code. But only 1 gridview is created. And also the problem is the button event is not firing
public void btn_Click(object sender, EventArgs e)
{
GridView gv = new GridView();
gv.ID = sender.ToString();
}
inside the class. How to fire this event?
This is the code I used to create gridview.
protected void btnAddGrid_Click(object sender,EventArgs e)
{
int count = Convert.ToInt32(Session["count"]);
DataTable dt=(DataTable)ViewState["CurrentTableforCommonDetails"];
GridView gv = new GridView();
gv.ID = "GridView" + count;
gv.AutoGenerateColumns = false;
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
TemplateField tmpfld = new TemplateField();
tmpfld.HeaderText = dt.Columns[i].ColumnName.ToString();
tmpfld.ItemTemplate =new DynamicTemplateField();
if (i == 0)
{
tmpfld.FooterTemplate = new DynamicTemplateField1();
}
gv.Columns.Add(tmpfld);
}
}
gv.Visible = true;
gv.ShowHeaderWhenEmpty = true;
gv.ShowFooter = true;
placegridview.Controls.Add(gv);
gv.DataSource = dt;
gv.DataBind();
count++;
Session["count"] = count;
}
public class DynamicTemplateField : ITemplate
{
public void InstantiateIn(System.Web.UI.Control container)
{
//define the control to be added , i take text box as your need
System.Web.UI.WebControls.TextBox txt1 = new System.Web.UI.WebControls.TextBox();
txt1.ID = "txt1";
txt1.Width = 50;
container.Controls.Add(txt1);
}
}
public class DynamicTemplateField1 : ITemplate
{
public void InstantiateIn(System.Web.UI.Control container)
{
//define the control to be added , i take text box as your need
System.Web.UI.WebControls.Button btn = new System.Web.UI.WebControls.Button();
btn.ID = "btn1";
btn.Click += new EventHandler(btn_Click);
btn.UseSubmitBehavior = false;
btn.Text = "Add New";
container.Controls.Add(btn);
}
public void btn_Click(object sender, EventArgs e)
{
GridView gv = new GridView();
gv.ID = sender.ToString();
}
}
This generally involves tracking (or maintaining state which stores) the fact that you have a dynamic control, and adding that control to the control tree really early on in the page lifecycle. The following example is not relevant to your question, but it demonstrates how to deal with dynamic controls
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApp.DynamicControls2
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ControlsCount = 0;
}
else
{
for (int i = 0, j = ControlsCount; i < j; i++)
{
CreateControl();
}
}
}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
}
int ControlsCount
{
get
{
if (ViewState["ControlsCount"] == null)
{
int count = 0;
ViewState["ControlsCount"] = count;
return count;
}
return (int)ViewState["ControlsCount"];
}
set
{
ViewState["ControlsCount"] = value;
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
CreateControl(true);
}
protected void btnCount_Click(object sender, EventArgs e)
{
}
void CreateControl(bool UpdateCount = false)
{
TextBox tbx = new TextBox();
Button btn = new Button() { Text = "Get Time" };
btn.Click += btn_Click;
Literal br = new Literal() { Text = "<br/>" };
var ctls = phContainer.Controls;
ctls.Add(tbx);
ctls.Add(btn);
ctls.Add(br);
if (UpdateCount) ControlsCount++;
}
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
Control parent = btn.Parent;
int index = parent.Controls.IndexOf(btn);
TextBox tbx = parent.Controls[index - 1] as TextBox;
tbx.Text = DateTime.Now.ToLongTimeString();
}
}
}
The webform associated with this code is:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.DynamicControls2.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Dynamic Controls</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="btnAdd_Click" />
<asp:Button ID="btnCount" runat="server" Text="Get Count" OnClick="btnCount_Click" />
</div>
<br />
<br />
<div>
<asp:PlaceHolder ID="phContainer" runat="server"></asp:PlaceHolder>
</div>
</form>
</body>
</html>
You should adapt your code likewise to ensure this effect.
If you want to understand terms such as tracking or control tree read the following article series. http://weblogs.asp.net/infinitiesloop/TRULY-Understanding-Dynamic-Controls-_2800_Part-1_2900_
Update 1:
There are various cases and it can become complicated based on requirement. The code for the most basic approach is shown below:
Webform (aspx):
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm3.aspx.cs" Inherits="WebApp.DynamicGridViewWithTemplateField.WebForm3" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<asp:Button ID="btn1" runat="server" Text="Clickme" />
</div>
</form>
</body>
</html>
Code-behind:
using System;
using System.Collections.Generic;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApp.DynamicGridViewWithTemplateField
{
public partial class WebForm3 : System.Web.UI.Page
{
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
CreateGrid();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (!IsPostBack)
{
CreateGrid();
ViewState["foo"] = "foo"; //forcing viewstate
}
}
}
private static DataTable GetNames()
{
DataTable tbl = new DataTable();
tbl.Columns.Add(new DataColumn("Name"));
List<string> names = new List<string>() { "Arun", "Samit", "Jermy", "John" };
names.ForEach(x =>
{
var row = tbl.NewRow();
row[0] = x;
tbl.Rows.Add(row);
});
return tbl;
}
void CreateGrid()
{
GridView gv = new GridView();
gv.AutoGenerateColumns = false;
gv.Columns.Add(new BoundField() {
HeaderText="Names",
DataField="Name"
});
gv.Columns.Add(new TemplateField()
{
ItemTemplate = new TextTemplateField(),
HeaderText = "Remarks"
});
gv.Columns.Add(new TemplateField()
{
ItemTemplate = new DropDownTemplateField(),
HeaderText="Choose option"
});
gv.Columns.Add(new TemplateField()
{
ItemTemplate = new ButtonTemplateField()
});
gv.RowCommand += (sndr, evt) =>
{
if (evt.CommandName == "foo")
{
Control ctrl = (Control)evt.CommandSource;
GridViewRow gvRow = (GridViewRow)ctrl.Parent.Parent;
var tbx = gvRow.FindControl("tbx1") as TextBox;
tbx.Text = DateTime.Now.ToLongTimeString();
}
};
gv.DataSource = GetNames();
gv.DataBind();
PlaceHolder1.Controls.Add(gv);
}
}
}
The ButtonTemplateField, DropDownTemplateField and TextTemplateField are simple templates, and correspondingly contain a Button, DropDownList, and TextBox respectively. Nothing really fancy there.
public class DropDownTemplateField : ITemplate
{
int[] options = new int[] { 1, 2, 3, 4 };
public void InstantiateIn(Control container)
{
DropDownList ddl = new DropDownList();
ddl.DataSource = options;
foreach (int value in options)
{
ddl.Items.Add(new ListItem(value.ToString(), value.ToString()));
}
container.Controls.Add(ddl);
}
}
public class ButtonTemplateField : ITemplate
{
public void InstantiateIn(Control container)
{
Button btn = new Button();
btn.CommandName = "foo";
btn.Text = "Click me";
container.Controls.Add(btn);
}
}
public class TextTemplateField : ITemplate
{
public void InstantiateIn(Control container)
{
TextBox tbx = new TextBox();
tbx.ID = "tbx1";
container.Controls.Add(tbx);
}
}
why My GridView was not displaying?
ascx CODE:
<asp:PlaceHolder ID="plcGridTest" runat="server">
<asp:GridView ID="grdTest" runat="server" AutoGenerateColumns="false"/>
</asp:PlaceHolder>
ascx.cs CODE:
protected void btnPesquisar_Click(object sender, EventArgs e)
{
string placa = string.Empty;
insereParameterPlaca(txtPlaca.Text.ToUpper(), out placa);
string transportadora = string.Empty;
transportadora = insereTransportadoraSelecionada();
string tiposWorkflow = string.Empty;
insereTiposWorkflow(chkBox_TiposOcorrencia.Items, out tiposWorkflow);
string cliente = string.Empty;
insereCliente(out cliente);
string query = string.Empty;
query = string.Format(SQL_GET_OCORRENCIAS_PARAMETRIZADO, placa, transportadora, tiposWorkflow, cliente);
using (var sqlDataAccess = new MSQLDataAccess(Util.GetIntegraConnectionString))
{
var datatable = sqlDataAccess.GetDataTable(query);
grdTest.Visible = true;
grdTest.DataSource = datatable;
grdTest.DataBind();
}
}
AutoGenarateColuns was marked as false and I'm runnig DataBind() command.
You should set AutoGenerateColumns="True", if you don't want to specify each column.
I'm using PostBackUrl to post my control from a "firstwebpage.aspx" to a "secondwebpage.aspx" so that I would be able to generate some configuration files.
I do understand that I can make use of PreviousPage.FindControl("myControlId") method in my secondwebpage.aspx to get my control from "firstwebpage.aspx"and hence grab my data and it worked.
However, it seems that this method does not work on controls which I generated programmically during runtime while populating them in a table in my firstwebpage.aspx.
I also tried using this function Response.Write("--" + Request["TextBox1"].ToString() + "--");
And although this statement do printout the text in the textfield on TextBox1, it only return me the string value of textbox1. I am unable to cast it to a textbox control in the following format too
TextBox temptextBox = (TextBox)Request["TextBox1"];
My question is, how can I actually access the control which i generated programmically in "firstwebpage.aspx" on "secondwebpage.aspx"?
Please advice!
thanks alot!
//my panel and button in aspx
<asp:Panel ID="Panel2" runat="server"></asp:Panel>
<asp:Button ID="Button1" runat="server" Text="Generate Xml" PostBackUrl="~/WebForm2.aspx" onclick="Button1_Click" />
//this is my function to insert a line into the panel
public void createfilerow(string b, string path, bool x86check, bool x86enable, bool x64check, bool x64enable)
{
Label blank4 = new Label();
blank4.ID = "blank4";
blank4.Text = "";
Panel2.Controls.Add(blank4);
CheckBox c = new CheckBox();
c.Text = b.Replace(path, "");
c.Checked = true;
c.ID = "1a";
Panel2.Controls.Add(c);
CheckBox d = new CheckBox();
d.Checked = x86check;
d.Enabled = x86enable;
d.ID = "1b";
Panel2.Controls.Add(d);
CheckBox e = new CheckBox();
e.Checked = x64check;
e.Enabled = x64enable;
e.ID = "1c";
Panel2.Controls.Add(e);
}
//my virtual path in WebForm2.aspx
<%# PreviousPageType VirtualPath="~/WebForm1.aspx" %>
//my pageload handler
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
CheckBox tempCheckbox = (CheckBox)Page.PreviousPage.FindControl("1a");
Button1.Text = tempCheckbox.Text;
}
}
//handler which will populate the panel upon clicking
protected void Button7_Click(object sender, EventArgs e)
{
//get foldername
if (!Directory.Exists(#"myfilepath" + TextBox2.Text))
{
//folder does not exist
//do required actions
return;
}
string[] x86files = null;
string[] x64files = null;
string[] x86filespath = null;
string[] x64filespath = null;
ArrayList common = new ArrayList();
if (Directory.Exists(#"myfilepath" + TextBox2.Text + "\\x86"))
x86files = Directory.GetFileSystemEntries("myfilepath" + TextBox2.Text + "\\x86");
if (Directory.Exists(#"myfilepath" + TextBox2.Text + "\\x64"))
x64files = Directory.GetFileSystemEntries("myfilepath" + TextBox2.Text + "\\x64");
//some codes to convert x64files and x86files to string[]
//The header for Panel, 4 column
Label FL = new Label();
FL.ID = "flavourid";
FL.Text = "Flavour";
Panel2.Controls.Add(FL);
Label filetext = new Label();
filetext.ID = "filenamelabel";
filetext.Text = "File(s)";
Panel2.Controls.Add(filetext);
Label label86 = new Label();
label86.ID = "label86";
label86.Text = "x86";
Panel2.Controls.Add(label86);
Label label64 = new Label();
label64.ID = "label64";
label64.Text = "x64";
Panel2.Controls.Add(label64);
//a for loop determine number of times codes have to be run
for (int a = 0; a < num; a++)
{
ArrayList location = new ArrayList();
if (//this iteration had to be run)
{
string path = null;
switch (//id of this iteration)
{
case id:
path = some network address
}
//check the current version of iternation
string version = //version type;
//get the platform of the version
string platform = //platform
if (curent version = certain type)
{
//do what is required.
//build a list
}
else
{
//normal routine
//do what is required
//build a list
}
//populating the panel with data from list
createflavourheader(a);
//create dynamic checkboxes according to the list
foreach(string s in list)
//createrow parameter is by version type and platform
createfilerow(readin, path, true, true, false, false);
}
}
}
form1.Controls.Add(Panel2);
}
Sorry can't show you the full code as it is long and I believe it should be confidential even though i wrote them all
Yes you can access, Below is an example
// On Page1.aspx I have a button for postback
<asp:Button ID="btnSubmit" runat="server" Text="Submit"
PostBackUrl="~/Page2.aspx" />
// Page1.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
TextBox t = new TextBox(); // created a TextBox
t.ID = "myTextBox"; // assigned an ID
form1.Controls.Add(t); // Add to form
}
Now on the second page I will get the value of TextBox as
// Page2.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
TextBox t = (TextBox) PreviousPage.FindControl("myTextBox");
string mytboxvalue = t.Text;
}
// OR
string myTextBoxValue = Request.Form["myTextBox"];
}
Updated Answer:
Panel myPanel = new Panel();
myPanel.ID = "myPanel";
TextBox t = new TextBox();
t.ID = "myTextBox";
myPanel.Controls.Add(t);
TextBox t1 = new TextBox();
t1.ID = "myTextBox1";
myPanel.Controls.Add(t1);
// Add all your child controls to your panel and at the end add your panel to your form
form1.Controls.Add(myPanel);
// on the processing page you can get the values as
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null)
{
TextBox t = (TextBox) PreviousPage.FindControl("myTextBox");
string mytboxvalue = t.Text;
}
string myTextBoxValue = Request.Form["myTextBox1"];
}
I also tried using this function Response.Write("--" +
Request["TextBox1"].ToString() + "--"); And although this statement do
printout the text in the textfield on TextBox1, it only return me the
string value of textbox1. I am unable to cast it to a textbox control
in the following format too
TextBox temptextBox = (TextBox)Request["TextBox1"];
Hi lw,
I think you may try passing the type of control (e.g. 'tb') together with the content and creating a new object (e.g. TextBox) and assign it to templtexBox object.
My 20 cents.
Andy
I am completly new in asp.net and I'm having some problems with it.
I created litle web form for demo and learning and I have some problems with it. Hopefuly you can help me :)
What I want is that:
when I click on "Kill X" button in table, I get "You pressed button Kill X" message in label "lblMsg". I Also want that I get table with new data.
when I click "Load" button, I need to get additional rows in the table. For example now when page loads there is 10 rows in table and when I click "Load" I nedd to get additional 10 rows at the end into the same table.
P.S:
I would be grateful for some tutorial how to deal with events in asp.net.
Bellow is the code:
WebForm1.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="HelpdeskOsControl.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:Panel ID="Panel1" runat="server" Height="465px" Width="417px">
<asp:Table ID="Processes" runat="server" Height="20px" Width="400px" CssClass="tablesorter">
<asp:TableHeaderRow ID="ProcessesHeader" runat="server"
TableSection="TableHeader">
<asp:TableHeaderCell ID="TableHeaderCell1" runat="server">Name</asp:TableHeaderCell>
<asp:TableHeaderCell ID="TableHeaderCell2" runat="server">CPU</asp:TableHeaderCell>
<asp:TableHeaderCell ID="TableHeaderCell3" runat="server">Memory</asp:TableHeaderCell>
<asp:TableHeaderCell ID="TableHeaderCell4" runat="server"></asp:TableHeaderCell>
</asp:TableHeaderRow>
</asp:Table>
<asp:Panel ID="Panel2" runat="server">
<asp:Button ID="btnLoad" runat="server" onclick="btnLoad_Click" Text="Load" />
<asp:Button ID="btnClear" runat="server" onclick="btnClear_Click"
Text="Clear" />
<asp:Label ID="lblMsg" runat="server" Text="Label"></asp:Label>
</asp:Panel>
</asp:Panel>
</form>
</body>
</html>
WebForm1.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace HelpdeskOsControl
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
GenerateTable(getTestData());
}
private List<string> getTestData()
{
List<string> tData = new List<string>();
Random rand = new Random();
for (int i = 0; i < 10; i++)
{
tData.Add("proc" + i + "_" + rand.Next(100) + "_" + rand.Next(100));
}
return tData;
}
protected void btnClear_Click(object sender, EventArgs e)
{
for (int i = Processes.Rows.Count; i > 1; i--)
{
Processes.Rows.RemoveAt(i - 1);
}
}
protected void btnLoad_Click(object sender, EventArgs e)
{
GenerateTable(getTestData());
}
protected void btnKill_Click(object sender, EventArgs e)
{
lblMsg.Text = "You pressed button " + ((Button)sender).Text;
}
private void GenerateTable(List<string> list)
{
int st = 0;
foreach (string line in list)
{
TableRow tr = new TableRow();
Processes.Controls.Add(tr);
foreach (String str in line.Split('_'))
{
int index = tr.Cells.Add(new TableCell());
tr.Cells[index].Text = str;
}
Button b = new Button();
b.Text = "Kill " + st;
b.ID = "btnKill_" + st;
b.Click += new EventHandler(btnKill_Click);
TableCell tc = new TableCell();
tc.Controls.Add(b);
tr.Cells.Add(tc);
tr.TableSection = TableRowSection.TableBody;
st++;
}
Processes.BorderStyle = BorderStyle.Solid;
Processes.GridLines = GridLines.Both;
Processes.BorderWidth = 2;
}
}
}-
I understand this is your first time with ASP.NET and want to help you learn more about its potentials.
First of all, I would replace the code you wrote with data binding, which is a way to easily build tables without having to write methods like your generateTable. ASP.NET takes care of building the table by itself. It will take me a while to illustrate you full code for achieving this, but I hope you can grab the documentation and start learning with my help.
The key control is GridView. It can be populated using a two-lines code fragment
protected override OnLoad(EventArgs e)
{
if (!IsPostback) DataBind();
}
protected override void OnDataBind(EventArgs e)
{
gridView.DataSource = getTestData();
gridView.DataBind();
}
You must first configure columns in layout. The articles about GridView deal with this, and you can add a button for each row.
Now,
you can set the buttons as command buttons, thus not only raising the Click event, but, more important, the Command event which takes a name and an argument. That's where you can inject your code. For example
<asp:Button id="btnSomething" CommandArgument="[procId]" CommandName="kill" OnCommand="myCommandHandler" />
protected void myCommandHandler(object sender, CommandEventArgs e)
{
if (e.CommandName=="kill")
{
killProcess(e.CommandArgument);
DataBind(); //MOST IMPORTANT
}
}
Hope to have been of help. I wrote this code by hand, so please understand me if it will not work immediately
You need to store the state of the table between page loads and regenerate it as the dynamic controls are not stored between requests. (An advantage of using a ListView, DataGrid etc.).
public partial class WebForm1 : System.Web.UI.Page
{
private List<string> CurrentTestData
{
get
{
if (ViewState["CurrentTestData"] == null)
return new List<string>();
else
return (List<string>)ViewState["CurrentTestData"];
}
set
{
ViewState["CurrentTestData"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
CurrentTestData = getTestData();
GenerateTable(CurrentTestData);
}
else
GenerateTable(CurrentTestData);
}
private List<string> getTestData()
{
List<string> tData = new List<string>();
Random rand = new Random();
for (int i = 0; i < 10; i++)
{
tData.Add("proc" + (CurrentTestData.Count + i) + "_" + rand.Next(100) + "_" + rand.Next(100));
}
return tData;
}
protected void btnClear_Click(object sender, EventArgs e)
{
ClearTheTable();
CurrentTestData = null;
}
protected void btnLoad_Click(object sender, EventArgs e)
{
var CombinedTestData = CurrentTestData;
CombinedTestData.AddRange(getTestData());
CurrentTestData = CombinedTestData;
GenerateTable(CurrentTestData);
}
protected void btnKill_Click(object sender, EventArgs e)
{
lblMsg.Text = "You pressed button " + ((Button)sender).Text;
}
private void GenerateTable(List<string> list)
{
ClearTheTable();
int st = 0;
foreach (string line in list)
{
TableRow tr = new TableRow();
Processes.Controls.Add(tr);
foreach (String str in line.Split('_'))
{
int index = tr.Cells.Add(new TableCell());
tr.Cells[index].Text = str;
}
Button b = new Button();
b.Text = "Kill " + st;
b.ID = "btnKill_" + st;
b.Click += new EventHandler(btnKill_Click);
TableCell tc = new TableCell();
tc.Controls.Add(b);
tr.Cells.Add(tc);
tr.TableSection = TableRowSection.TableBody;
st++;
}
Processes.BorderStyle = BorderStyle.Solid;
Processes.GridLines = GridLines.Both;
Processes.BorderWidth = 2;
}
private void ClearTheTable()
{
for (int i = Processes.Rows.Count; i > 1; i--)
{
Processes.Rows.RemoveAt(i - 1);
}
}
}
Two nice links for you:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.click.aspx
http://www.youcanlearnseries.com/Programming%20Tips/CSharp/SetEvents.aspx