ASP.NET controls C# - asp.net

I am trying to get value from the databse and assign it to the label using the below line:
lblQuestion.Text = ds.Tables[0].Rows[0]["Question"].ToString();
but it assigns as label.
if (ds.Tables[0].Rows.Count > 0)
{
lblQuestion.Text = ds.Tables[0].Rows[0]["Question"].ToString(); ;
}

UPDATED - Deleted my last info now that you have included the code....
Have you stepped through your code to see if any data is returning?
AKA - is ds.Tables[0].Rows.Count > 0 ?
You are also doing !Page.IsPostBack. This will only call the code and load your labels if it's on the first load.... What about subsequent loads? The labels will return back to whatever they defaulted to in the designer.....

I've put together a test-case in a web app as follows:
ASPX Code-behind:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var ds = new DataSet();
var table = new DataTable();
table.Columns.Add("Question", typeof(string));
table.Rows.Add(new object[] { "This is the question" });
ds.Tables.Add(table);
lblQuestion.Text = ds.Tables[0].Rows[0]["Question"].ToString();
}
}
ASPX Page:
<form id="form1" runat="server">
<div>
<asp:Label runat="server" ID="lblQuestion"></asp:Label>
</div>
</form>
This renders out correctly as:
<div>
<span id="lblQuestion">This is the question</span>
</div>
Are you sure you've shown us the code that's actually running?

protected void Page_Load(object sender, EventArgs e)
{
//if (Request.QueryString["QID"] != null)
//{
// Response.Write(Request.QueryString["QID"].ToString());
//}
if (!Page.IsPostBack)
{
int i = Convert.ToInt32(Request.QueryString["QID"]);
// Response.Write(i);
eTutorService ServiceProvider = new eTutorService();
DataSet ds = new DataSet();
ds = ServiceProvider.GetQuestionView(i);
if (ds.Tables[0].Rows.Count > 0)
{
lblQuestion.Text = ds.Tables[0].Rows[0]["Question"].ToString(); ;
lblOption1.Text = ds.Tables[0].Rows[0]["Option1"].ToString();
lblOption2.Text = ds.Tables[0].Rows[0]["Option2"].ToString();
lblOption3.Text = ds.Tables[0].Rows[0]["Option3"].ToString();
lblOption4.Text = ds.Tables[0].Rows[0]["Option4"].ToString();
lblCorrectOption.Text = ds.Tables[0].Rows[0]["CorrectAnswer"].ToString();
lblPaper.Text = ds.Tables[0].Rows[0]["subject"].ToString();
lblDifficultyLevel.Text = ds.Tables[0].Rows[0]["LEVEL_NAME"].ToString();
lblquestionOrder.Text = ds.Tables[0].Rows[0]["QuestionOrder"].ToString();
}
}
}
Its just put label rather than putting database value to the label

Related

Why this gridview is empty and how I can better check null?

What's wrong in this code? Code works, but it returns empty gridview?
If I debug code, I can see that my string plName contains players name, however when I add it to object it's empty? Also, how I can check if my query result is null? I believe this is not best way to do it...
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback)
{
List<AllPlayers> listOfPlayers = new List<AllPlayers>();
string plName = "";
string plStatus = "";
using (PlayerEntities playerEntities = new PlayerEntities())
{
var query = (from pl in playerEntities.players from st in playerEntities.player_status.Where(a => a.players_key == pl.players_key).DefaultIfEmpty()
from pt in playerEntities.play_times.Where(b => b.players_key == pl.players_key).DefaultIfEmpty() select new { pl, st, pt }).ToList();
foreach (var item in query)
{
plName = item.pl.player_name.ToString();
try // better way check if this is NULL ?
{
plName = item.st.default_times_start.ToString();
}
catch(Exception ex)
{
ex.Message.ToString();
}
AllPlayers demo = new AllPlayers(plName, plStatus);
listOfPlayers.Add(demo);
}
}
GridView1.DataSource = listOfPlayers;
GridView1.DataBind();
}
}
ASPX:
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</div>
</form>

Creating dynamic controls in Page_PreRender based on viewstate causes button OnClick event to not work

I realize that dynamic controls should be created within Page_Load and Page_Init in order for them to be registered in the control tree.
I have created a custom control that requires the use of ViewState in a button OnClick event. This ViewState is then used to dynamically create controls.
Since the life-cycle will go: Page Load -> Button Click -> Page PreRender. The view-state will not be updated until "Button Click", thus I am creating my dynamic controls in Page PreRender. However, creating a button and programatically assigning the OnClick EventHandler in Page_PreRender does not work.
Does anyone know how I can get this to work?
btn_DeleteTableRow_Click will not fire. This is setup in CreatePartRows()
Here is my example:
<asp:UpdatePanel ID="up_RMAPart" runat="server" UpdateMode="Conditional" EnableViewState="true" ChildrenAsTriggers="true">
<ContentTemplate>
<div class="button" style="width: 54px; margin: 0px; float: right;">
<asp:Button ID="btn_AddPart" runat="server" Text="Add" OnClick="btn_AddPart_Click" />
</div>
<asp:Table ID="Table_Parts" runat="server" CssClass="hor-zebra">
</asp:Table>
<div class="clear"></div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btn_AddPart" EventName="Click" />
</Triggers>
Code Behind:
[Serializable]
public struct Part
{
public string PartName;
public int Quantity;
public int PartID;
public Part(string sPartName, int iQuantity, int iPartID)
{
PartName = sPartName;
Quantity = iQuantity;
PartID = iPartID;
}
}
public partial class RMAPart : System.Web.UI.UserControl
{
private Dictionary<string,Part> m_RMAParts;
private int m_RowNumber = 0;
public Dictionary<string, Part> RMAParts
{
get
{
if (ViewState["m_RMAParts"] != null)
return (Dictionary<string, Part>)ViewState["m_RMAParts"];
else
return null;
}
set
{
ViewState["m_RMAParts"] = value;
}
}
public int RowNumber
{
get
{
if (ViewState["m_RowNumber"] != null)
return Convert.ToInt32(ViewState["m_RowNumber"]);
else
return 0;
}
set
{
ViewState["m_RowNumber"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
RMAParts = new Dictionary<string, Part>();
RowNumber = 0;
RMAParts.Add("PartRow_" + RowNumber.ToString(), new Part());
RowNumber = 1;
CreatePartRows();
}
}
protected void Page_PreRender(object sender, EventArgs e)
{
CreatePartRows();
}
private void CreatePartRows()
{
Table_Parts.Controls.Clear();
TableHeaderRow thr = new TableHeaderRow();
TableHeaderCell thc1 = new TableHeaderCell();
thc1.Controls.Add(new LiteralControl("Part"));
thr.Cells.Add(thc1);
TableHeaderCell thc2 = new TableHeaderCell();
thc2.Controls.Add(new LiteralControl("Quantity"));
thr.Cells.Add(thc2);
TableHeaderCell thc3 = new TableHeaderCell();
thc3.Controls.Add(new LiteralControl(""));
thr.Cells.Add(thc3);
Table_Parts.Rows.Add(thr);
foreach (KeyValuePair<string, Part> kvp in RMAParts)
{
string[] sKey = kvp.Key.Split('_');
TableRow tr = new TableRow();
tr.ID = kvp.Key;
TableCell tc1 = new TableCell();
TextBox tb_Part = new TextBox();
tb_Part.ID = "tb_Part_" + sKey[1];
tb_Part.CssClass = "textbox1";
tc1.Controls.Add(tb_Part);
tr.Cells.Add(tc1);
TableCell tc2 = new TableCell();
TextBox tb_Quantity = new TextBox();
tb_Quantity.ID = "tb_Quanitty_" + sKey[1];
tb_Quantity.CssClass = "textbox1";
tc2.Controls.Add(tb_Quantity);
tr.Cells.Add(tc2);
TableCell tc3 = new TableCell();
Button btn_Delete = new Button();
btn_Delete.ID = "btn_Delete_" + sKey[1];
btn_Delete.CommandArgument = tr.ID;
btn_Delete.Click += new EventHandler(btn_DeleteTableRow_Click);
btn_Delete.Text = "Remove";
tc3.Controls.Add(btn_Delete);
tr.Cells.Add(tc3);
Table_Parts.Rows.Add(tr);
}
}
public void Reset()
{
Table_Parts.Controls.Clear();
RMAParts.Clear();
RowNumber = 0;
RMAParts.Add("PartRow_" + RowNumber.ToString(), new Part());
RowNumber = 1;
CreatePartRows();
}
protected void btn_AddPart_Click(object sender, EventArgs e)
{
RMAParts.Add("PartRow_" + RowNumber.ToString(), new Part());
RowNumber++;
}
protected void btn_DeleteTableRow_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
TableRow tr = (TableRow)Table_Parts.FindControl(btn.CommandArgument);
Table_Parts.Rows.Remove(tr);
RMAParts.Remove(btn.CommandArgument);
}
}
To ensure that the values of input fields persist across postbacks and that server events are raised:
Use view state to keep track of dynamically created controls.
Re-create the controls with the same IDs in LoadViewState (not Load or PreRender, because then the values of input fields will be lost).
The rest of this answer details how I modified your code to get it to work.
RMAPart.ascx
Just for convenience, you can declare the header row in the .ascx:
<asp:Table ID="Table_Parts" runat="server" CssClass="hor-zebra">
<asp:TableRow>
<asp:TableHeaderCell Text="Part" />
<asp:TableHeaderCell Text="Quantity" />
<asp:TableHeaderCell />
</asp:TableRow>
</asp:Table>
RMAPart.ascx.cs
To keep track of dynamically created rows, maintain a list of row IDs in view state:
public partial class RMAPart : System.Web.UI.UserControl
{
private List<string> RowIDs
{
get { return (List<string>)ViewState["m_RowIDs"]; }
set { ViewState["m_RowIDs"] = value; }
}
In the btn_AddPart_Click handler, generate a new row ID and create the controls for the new row:
protected void btn_AddPart_Click(object sender, EventArgs e)
{
string id = GenerateRowID();
RowIDs.Add(id);
CreatePartRow(id);
}
private string GenerateRowID()
{
int id = (int)ViewState["m_NextRowID"];
ViewState["m_NextRowID"] = id + 1;
return id.ToString();
}
private void CreatePartRow(string id)
{
TableRow tr = new TableRow();
tr.ID = id;
TableCell tc1 = new TableCell();
TextBox tb_Part = new TextBox();
tb_Part.ID = "tb_Part_" + id;
tb_Part.CssClass = "textbox1";
tc1.Controls.Add(tb_Part);
tr.Cells.Add(tc1);
TableCell tc2 = new TableCell();
TextBox tb_Quantity = new TextBox();
tb_Quantity.ID = "tb_Quantity_" + id;
tb_Quantity.CssClass = "textbox1";
tc2.Controls.Add(tb_Quantity);
tr.Cells.Add(tc2);
TableCell tc3 = new TableCell();
Button btn_Delete = new Button();
btn_Delete.ID = "btn_Delete_" + id;
btn_Delete.CommandArgument = id;
btn_Delete.Click += btn_DeleteTableRow_Click;
btn_Delete.Text = "Remove";
tc3.Controls.Add(btn_Delete);
tr.Cells.Add(tc3);
Table_Parts.Rows.Add(tr);
}
In the btn_DeleteTableRow_Click handler, delete the clicked row and update view state:
protected void btn_DeleteTableRow_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
TableRow tr = (TableRow)Table_Parts.FindControl(btn.CommandArgument);
Table_Parts.Rows.Remove(tr);
RowIDs.Remove(btn.CommandArgument);
}
Hook Page_Load and start things off by creating the first row:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Reset();
}
}
public void Reset()
{
while (Table_Parts.Rows.Count > 1)
Table_Parts.Rows.RemoveAt(Table_Parts.Rows.Count - 1);
ViewState["m_NextRowID"] = 0;
string id = GenerateRowID();
RowIDs = new List<string> { id };
CreatePartRow(id);
}
Override LoadViewState and re-create the rows using the IDs stored in view state:
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
foreach (string id in RowIDs)
{
CreatePartRow(id);
}
}
}
Dealing with Parts
The code above doesn't use your Part structure at all. To actually move data between your business objects and the user control, you can add a public method that takes a Part collection and uses it to create rows and populate text boxes, and then add another public method that reads out the values of the text boxes into a Part collection.
The button click isn't being fired because control events are called right after the Load event. Your button isn't in the control hierarchy at the time that the asp.net lifecycle is trying to call your event, so it's being dropped. Remember, it's a round-trip and the control has to exist on postback before the LoadComplete event fires for its event handlers to get called.
Create your dynamic controls in the PreLoad or Load event and you should be OK (you will have access to the full viewstate at that time to make any decisions regarding whether or not you need to dynamically create your delete button for that row).
ASP.net Page Lifecycle Docs: http://msdn.microsoft.com/en-us/library/ms178472(v=vs.100).aspx
I think that Robert has the right answer, but needs to be more clear about WHICH Page.Load he is talking about. There are three page requests here.
Initial Page request, no initial button click yet.
Postback on button click. No processing in Page Load. PreRender call creates the new table rows and the new button and links up the button click event to the new button.
Postback after the client clicks on the new button. You need to re-create the dynamic button in Page Load so that the Click event of the dynamic button doesn't get dropped.
Agree with Robert and Bill.
But to add here, in my opinion only way that you would achieve this is by creating a custom control/web server control (inheriting WebControl class), where you override the CreateChildControls method and RenderContents methods. I think this is what you mean when you said, in one of your comments, you are going to code out a grid-view version.

asp.net Recreating Dynamically Added ListBox controls on PostBack

So I almost have this working. I create Dynamic ListBoxes based on user selection. Always when the user loads the page for the first time there will only be one ListBox with the Top level categories shown (ones with no parent). I have categories with subcategories. That can be many subcategories like so
Cat 1
Cat 2
Cat 2.1
Cat 2.2
-- Cat 2.2.1
--- Cat 2.2.1.1
and so on.
The problem I am having is clearing the Listboxes if a user select a value from an already shown listbox. So if there are 4 Listboxes shown and the user slects a new value from the first listbox which shows that top tear categories with no parent, all Listboxes should go away and the new one should appear. If there is 4 Listboxes and the user clicks on an new item in ListbOx 3 the 4th should rerender with the subcategories to its selected parent. i hope I am explaining myself correctly.
Here is my code thus far:
public partial class WebForm2 : System.Web.UI.Page
{
private Int32 controlCount = 0;
Panel _panel;
private Panel PanelPlaceholder
{
get
{
if (_panel == null && Master != null)
_panel = pnlContainer;
return _panel;
}
}
protected void Page_PreInit(Object sender, EventArgs e)
{
this.EnsureChildControls();
if (IsPostBack)
{
// Re-create controls but not from datasource
// The controlCount value is output in the page as a hidden field during PreRender.
controlCount = Int32.Parse(Request.Form["controlCount"]); // assigns control count from persistence medium (hidden field)
for (Int32 i = 0; i < controlCount; i++)
{
CreateDynamicControlGroup(false);
}
}
}
protected void Page_Load(Object sender, EventArgs e)
{
if (!IsPostBack)
{
int cc = controlCount;
DataTable dt = null;
Dictionary<string, string> Params = new Dictionary<string, string>();
dt = Globals.g_DatabaseHandler.GetRecords(StoredProcedures.GetMainCategories, Params);
CreateDynamicControlGroup(true);
ListBox lb = (ListBox)PanelPlaceholder.Controls[controlCount - 1];
lb.DataSource = dt;
lb.DataValueField = "ID";
lb.DataTextField = "Name";
lb.DataBind();
}
}
protected void Page_PreRender(Object sender, EventArgs e)
{
// persist control count
ClientScript.RegisterHiddenField("controlCount", controlCount.ToString());
}
private void ListBox_SelectedIndexChanged(Object sender, EventArgs e)
{
ListBox lb = sender as ListBox;
Dictionary<string, string> Params = new Dictionary<string, string>();
Params.Add("parentID", lb.SelectedValue);
DataTable Categories = Globals.g_DatabaseHandler.GetRecords(StoredProcedures.GetChildCategories, Params);
if (Categories.Rows.Count > 0)
{
CreateDynamicControlGroup(true);
ListBox newLb = (ListBox)PanelPlaceholder.Controls[controlCount - 1];
newLb.DataSource = Categories; // use the same table
newLb.DataValueField = "ID";
newLb.DataTextField = "Name";
newLb.DataBind();
}
}
private void CreateDynamicControlGroup(Boolean incrementCounter)
{
// Create one logical set of controls do not assign values!
ListBox lb = new ListBox();
lb.AutoPostBack = true;
lb.CssClass = "panel";
PanelPlaceholder.Controls.Add(lb);
// wire event delegate
lb.SelectedIndexChanged += new EventHandler(ListBox_SelectedIndexChanged);
if (incrementCounter)
{
controlCount += 1;
}
}
}
Here is my markup:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<div class="Column12" id="Form_NewListing">
<h2 class="h2row">Create Your Listing - Step 1 of 2)</h2>
<h3 class="h3row">Select a category</h3>
<div class="panel">
<asp:Panel ID="pnlContainer" runat="server"></asp:Panel>
</div>
</div>
Thanks in advance.
What about adding
int index = PanelPlaceholder.Controls.IndexOf((ListBox)sender);
for (int i = index + 1; i < PanelPlaceholder.Controls.Count; i++)
PanelPlaceholder.Controls.RemoveAt(index + 1);
to the beginning of your ListBox_SelectedIndexChanged method?
int index = PanelPlaceholder.Controls.IndexOf((ListBox)sender);
for (int i = PanelPlaceholder.Controls.Count - 1; i > index; i--)
{
PanelPlaceholder.Controls.RemoveAt(i);
controlCount--;
}

asp.net gridview outside button to save

I have gridview built dynamically at run-time bind to datatable, and button to save gridview data placed outside gridview
1- Create GridView
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CreateGrid();
}
}
void CreateGrid()
{
int nTransID = Convert.ToInt32(Session["trans_id"]);
//
string strSQL = #"EXEC [dbo].[sp_GetTransaction] " + nTransID;
DataTable dtData = clsGlobal.GetDataTable(strSQL);
//
if (ViewState["dtTransDetail"] == null) ViewState.Add("dtTransDetail", dtData);
else ViewState["dtTransDetail"] = dtData;
//
foreach (DataColumn dc in dtData.Columns)
{
if (dc.ColumnName.Contains("!;"))
{
TemplateField tField = new TemplateField();
tField.ItemTemplate = new AddTemplateToGridView(ListItemType.Item, dc.ColumnName);
//\\ --- template contain textbox
tField.HeaderText = dc.ColumnName;
GridView1.Columns.Add(tField);
}
}
}
This is my template class:
public class AddTemplateToGridView : ITemplate
{
ListItemType _type;
string _colName;
public AddTemplateToGridView(ListItemType type, string colname)
{
_type = type;
_colName = colname;
}
void ITemplate.InstantiateIn(System.Web.UI.Control container)
{
switch (_type)
{
case ListItemType.Item:
TextBox text = new TextBox();
text.ID = "txtAmount";
text.DataBinding += new EventHandler(txt_DataBinding);
container.Controls.Add(text);
break;
}
}
void txt_DataBinding(object sender, EventArgs e)
{
TextBox textBox = (TextBox)sender;
GridViewRow container = (GridViewRow)textBox.NamingContainer;
object dataValue = DataBinder.Eval(container.DataItem, _colName);
if (dataValue != DBNull.Value)
{
textBox.Text = dataValue.ToString();
}
}
}
So i have a gridview with textboxe's all open to edit at once
The problem is, when i click on Save button "which is outside gridview" all textboxe's gone
protected void btnSave_Command(object sender, CommandEventArgs e)
{
for (int nRow = 0; nRow < GridView1.Rows.Count; nRow++)
{
for (int nCol = 0; nCol < GridView1.Columns.Count; nCol++)
{
if (GridView1.Rows[nRow].Cells[nCol].Controls.Count == 0) continue;
//\\ --- Controls.Count always = 0
//\\ --- However each cell contain textbox
//\\ --- textbox disappear after save button clicked
TextBox txt = (TextBox)GridView1.Rows[nRow].Cells[nCol].Controls[0];
}
}
}
It looks like you are not creating the GridView after a postback, and the Save button is causing a postback. You need to dynamically create the GridView on each page load. Also, I have found this documentation on the ASP.NET page lifecycle helpful on numerous occasions.
In the documentation, you will see the slightly unintuitive reason why your code isn't working as you would like - btnSave_Command is not run until after a postback and Page_Load.

CommandButton event not firing

I am populating an html table from a datatable with an edit button in each table row for each datatable row.
I am adding the edit button in code as follows:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (UserName != null && UserName != "")
{
hUserName.Value = UserName;
}
else
if (hUserName.Value != "")
UserName = hUserName.Value;
ShowTrainingEntry();
ShowUserTraining(); <-------------- this method populates table
hTID.Value = TrainingID.ToString();
}
}
public void ShowUserTraining()
{
....
dTotalTrainingHours += ShowTrainingInPeriod(dv);
....
}
protected decimal ShowTrainingInPeriod(DataView dv)
{
....
foreach (DataRowView rowView in dv)
{
....
Button bEdit = new Button();
int iTID = Convert.ToInt32(dr["ID"].ToString());
bEdit.Text = "Edit";
bEdit.ID = "btnEdit_" + iTID.ToString();
bEdit.CommandName = "Edit";
bEdit.CommandArgument = iTID.ToString();
bEdit.Command += new CommandEventHandler(btnEdit_Click);
....
}
....
}
public void btnEdit_Click(object sender, CommandEventArgs e)
{
clsLog.WriteLog("btnEdit_Click fired.");
clsLog.WriteLog("\t" + e.CommandName);
clsLog.WriteLog("\t" + e.CommandArgument.ToString());
UserName = hUserName.Value;
TrainingID = Convert.ToInt32(e.CommandArgument);
ShowTrainingEntry();
ShowUserTraining();
}
as requested - HTML table:
<asp:Table ID="tblMain" runat="server" Width="900" CellPadding="3" CellSpacing="0" CssClass="noborder">
</asp:Table>
btnEdit_Click is NOT being fired (no log entries).
I have researched this for several hours and the only thing consistent I have found is that the event must be wired to the button during Page_Load which I believe is happening correctly.
Any help would be greatly appreciated.
Thanks,
John
try to do event register
btnEdit_Click.Click += new EventHandler(this.btnEdit_Click);

Resources