I have a page in ASP .NET where when I access it, programmatically I set a value in the TextBox. When I click on the Button, I would like to update that value, but it gives me error:
Object not defined
Here is my code:
public partial class InsertValues : System.Web.UI.Page
{
DataProvider dataProvider = new DataProvider(); // This class contains all the querys I need to pull data
public MyValuesClass myValues; // This is my class where I get the data from my DB
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
startMyPage(); // Function that gets the values from the DataBase and sets my TextBox with the values.
}
else
{
}
}
private void startMyPage()
{
myValues = dataProvider.getValuesFromDB(); // Function that gets the values from a query and put them in my class, the values are. String "Banana" and Bool isNew = True
if (!myValues.isNew) //
{
txtFood.Text = myValues.food
}
else
{
myValues= new myValues();
myValues.isNew = true;
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
if (myValues.isNew) // Object not defined.
{
dataProvider.addMyValues(myValues); // It Inserts into my DB
}
else
{
dataProvider.editMyValues(myValues); // It Updates into my DB
}
}
}
Basically, after I click on my "btnSave" the class myValues becomes null, and I get the error Object not defined, is there a way to maintain the class Values?
You need to refetch your myValues object on PostBack.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
startMyPage();
}
else
{
myValues = dataProvider.getValuesFromDB();
}
}
Only data that's stored in the ViewState or equivalent persistence mechanism will be kept between the initial page load and post backs, which is why values of your webforms page controls are persisted, but your code behind property isn't.
You can store things manually in the ViewState like this: ViewState["someKey"] = someObject;, but someObject has to be serializable. It looks like myValues is an ORM object, so it probably isn't serializable.
All Variables are re-initiated at every post back. you better store your class public MyValuesClass myValues in session or viewstate.
Related
I have a user control that makes substantial use of this.ViewState["Key"] = SomeValue. Most of it is loaded from my Page_Init():
protected void Page_Init(object sender, EventArgs e)
{
if(!IsPostBack)
{
ViewState["Blahblah"] = LoadSomeValue();
}
}
The rest are set at various points.
But for some reason it's unavailable on subsequent postbacks. I overrode SaveViewState() to check, and only like three of them are saved!
protected override object SaveViewState()
{
List<object> viewStateObjectsBefore = ViewState.OfType<object>().ToList();
object ret = base.SaveViewState();
List<object> viewStateObjectsAfter = ViewState.OfType<object>().ToList();
GC.KeepAlive(viewStateObjectsBefore);
GC.KeepAlive(viewStateObjectsAfter);
GC.KeepAlive(ret);
return ret;
}
Both viewStateObjectsBefore and viewStateObjectsAfter contain 10 key/value pairs, but ret only contains three!
Added: Moving the initializations to Page_Load() is not an easily available option, because the initializations must be done before the parent's Page_Load() executes.
Adding a call to SetDirty() at the end of my Page_Init() solved the problem:
protected void Page_Init(object sender, EventArgs e)
{
if(!IsPostBack)
{
ViewState["Blahblah"] = LoadSomeValue();
//Looks like the ViewState is not yet "tracking" changes before Page_Load.
//The items have to be marked as "dirty" manually so they'll be included by SaveViewState().
ViewState.SetDirty(true);
}
}
I have two pages. first.aspx and second.aspx. In order to get all the control values from first.aspx, i added directive to second.aspx
<%# PreviousPageType VirtualPath="~/PR.aspx" %>
I have no problem to get all the previous page controls and set it to labels, but i have a big problem to save those values to a private variable, and reuse it after page load event is done. Here is code example. when i try to get the value from input in another method, it has nothing added. Why?
public partial class Second : System.Web.UI.Page
{
List<string> input = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
if (Page.PreviousPage != null&&PreviousPage.IsCrossPagePostBack == true)
{
TextBox SourceTextBox11 (TextBox)Page.PreviousPage.FindControl("TextBox11");
if (SourceTextBox11 != null)
{
Label1.Text = SourceTextBox11.Text;
input.Add(SourceTextBox11.Text);
}
}
}
protected void SubmitBT_Click(object sender, EventArgs e)
{
//do sth with input list<string>
//input has nothing in it here.
}
}
The SubmitBT_Click-click event happens in a postback. But all variables (and controls) are disposed at the end of the page's lifecycle. So you need a way to persist your List, e.g. in the ViewState or Session.
public List<String> Input
{
get
{
if (Session["Input"] == null)
{
Session["Input"] = new List<String>();
}
return (List<String>)Session["Input"];
}
set { Session["Input"] = value; }
}
Nine Options for Managing Persistent User State in Your ASP.NET Application
namespace Dynamic_Controls.Dropdowndynamic
{
public partial class DropdowndynamicUserControl : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (ControlCount != 0)
{
Recreatecontrols();
}
}
private void Recreatecontrols()
{
// createtextboxes(ControlCount);
createtextboxes(2);
}
protected void createtextboxes(int ControlCount)
{
DynPanel.Visible = true;
for (int i = 0; i <= ControlCount; i++)
{
TextBox tb = new TextBox();
tb.Width = 150;
tb.Height = 18;
tb.TextMode = TextBoxMode.SingleLine;
tb.ID = "TextBoxID" + this.DynPanel.Controls.Count;
tb.Text = "EnterTitle" + this.DynPanel.Controls.Count;
tb.Load+=new EventHandler(tb_Load);
tb.Visible = true;
tb.EnableViewState = true;
DynPanel.Controls.Add(tb);
DynPanel.Controls.Add(new LiteralControl("<br/>"));
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
Int32 newControlCount = Int32.Parse(DropDownList1.SelectedValue);
//createtextboxes(newControlCount);
//ControlCount+=newControlCount;
createtextboxes(2);
}
protected void Button1_Click(object sender, EventArgs e)
{
readtextboxes();
}
public void readtextboxes()
{
string x = string.Empty;
for (int a = 0; a < DynPanel.Controls.Count; a++)
{
foreach (Control ctrl in DynPanel.Controls)
{
if (ctrl is TextBox)
{
x = ((TextBox)ctrl).Text;
}
x+=x+("\n");
}
Result.Text = x;
}
}
private Int32 ControlCount
{
get
{
if (ViewState["ControlCount"] == null)
{
ViewState["ControlCount"] = 0;
}
return (Int32)ViewState["ControlCount"];
}
set
{
// ViewState["ControlCount"] = value;
ViewState["ControlCount"] = 2;
}
}
private void tb_Load(object sender, EventArgs e)
{
LblInfo.Text = ((TextBox)sender).ID + "entered";
}
}
}
Are you adding these controls dynamically in Page_Load (by, I'm assuming, calling your AddRequiredControl() method)? If so, is it wrapped in a conditional which checks for IsPostBack? The likely culprit is that you're destructively re-populating the page with controls before you get to the button click handler, so all the controls would be present but empty (as in an initial load of the page).
Also, just a note, if you're storing each control in _txt in your loop, why not refer to that variable instead of re-casting on each line. The code in your loop seems to be doing a lot of work for little return.
You need to recreate any dynamically created controls on or before Page_Load or they won't contain postback data.
I'm not entirely clear what happens on DropdownList changed - are you trying to preserve anything that has been entered already based on the textboxes previously generated?
In any event (no pun intended) you need to recreate exactly the same textboxes in or before Page_Load that were there present on the postback, or there won't be data.
A typical way to do this is save something in ViewState that your code can use to figure out what to recreate - e.g. the previous value of the DropDownList. Override LoadViewState and call the creation code there in order to capture the needed value, create the textboxes, then in the DropDownList change event, remove any controls that may have been created in LoadViewState (after of course dealing with their data) and recreate them based on the new value.
edit - i can't figure out how your code works now, you have AddRequiredControl with parameters but you call it with none. Let's assume you have a function AddRequiredControls that creates all textboxes for a given DropDownList1 value, and has this signature:
void AddRequiredControls(int index)
Let's also assume you have a PlaceHolder called ControlsPlaceholder that will contain the textboxes. Here's some pseudocode:
override void LoadViewState(..) {
base.LoadViewState(..);
if (ViewState["oldDropDownIndex"]!=null) {
AddRequiredControls((int)ViewState["oldDropDownIndex"]);
}
}
override OnLoad(EventArgs e)
{
// process data from textboxes
}
void DropDownList1_SelectedIndexChanged(..) {
ControlsPlaceholder.Controls.Clear();
AddRequiredControls(DropDownList1.SelectedIndex);
ViewState["oldDropDownIndex"]=DropDownList1.SelectedIndex;
}
I have SqlDataSource and GridView on web form. GridView.DataSourceID = mySqlDataSource.
When I call myGridView.DataBind(), all data successfully bind on the page.
How is it possible to read already got data from mySqlDataSource or myGridView objects as DataTable or DataView? Thanks
The data in the gridview can read by using FindControl property of Gridview control. For example, for reading values set in the Checkbox column in the grid.
for (i = 0; i < GridView1.Rows.Count; i++)
{
CheckBox chk = (CheckBox)GridView1.Rows[i].FindControl("checkbox1");
//here code for using value captured in chk
}
Provided your data set isn't gigantic, you could store it in the Session, bind your GridView to the Session data, and then re-use the Session data in your other web objects.
Your code would then look something like this (you'll have to forgive any minor inaccuracies -- I'm away from my development box at the moment):
protected override OnInit(object sender, EventArgs e)
{
base.OnInit();
if (Page.IsPostback == false)
{
SetSessionData();
}
//
// Set your GridView, DataTable, DataView, etc. events here.
//
}
void SetSessionData();
{
List<YourDataBoundObject> myDataBoundObject = GetYourDataBoundObject(); // Or Collection<T>, IEnumerable<T>, etc.
Session["data"] = myDataBoundObject;
}
void YourGridView_Load(object sender, EventArgs e)
{
BindYourGridView();
}
void BindYourGridView()
{
YourGridView.DataSource = GetSessionData();
YourGridView.DataBind();
}
List<YourDataBoundObject> GetSessionData()
{
return (List<YourDataBoundObject>) Session["data"];
}
void YourDataTable_Load(object sender, EventArgs e)
{
BindYourDataTable();
}
void BindYourDataTable()
{
YourDataTable.DataSource = GetSessionData();
YourDataTable.DataBind();
}
I'm trying to set the where clause on a LinqDataSource object bound to a GridView programmatically on a button click, but when the GridView rebinds data (for instance, when the user sorts) the Where clause resets back to the empty string. Is there a way to prevent this, or is there a better way to filter my results?
Perhaps you just add a ViewState property into your page/user control and then retrieve it on all post back?
public string MyLinqSourceWhere
{
get { return (string)this.ViewState["MyLinqSourceWhere"]; }
set { this.ViewState["MyLinqSourceWhere"] = value; }
}
public void Page_Load(object sender, EventArgs e)
{
this.myLinqSource.Where = this.MyLinqSourceWhere;
}
public void Button1_Click(object sender, EventArgs e)
{
this.MyLinqSourceWhere = " .... ";
this.myLinqSource.Where = this.MyLinqSourceWhere;
}
If that doesn't work, then perhaps bind on the LinqDataSource.Selecting event the fetch property from the viewstate to your where clause?? It all depends