I am stuck with following issue.I've google a lot and try every method but could not solve issue
I am creating control dynamically and after that reading value from dynamically created control
but every time I get error "Object reference is not set to an instance of an object" means I am not able to locate the control even if it available on page.
here is my code
protected void Button1_Click(object sender, EventArgs e)
{
TextBox txt = new TextBox();
txt.ID = "myText";
txt.ViewStateMode = System.Web.UI.ViewStateMode.Enabled;
Panel1.Controls.Add(txt);
}
protected void Button2_Click(object sender, EventArgs e)
{
TextBox txt = Panel1.FindControl("myText") as TextBox;
Response.Write(txt.Text);
}
Here is aspx page code :
<div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<asp:Panel ID="Panel1" runat="server"></asp:Panel>
<asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click"/>
</div>
That's because you create the control when Button1 is clicked, and then try and access it when Button2 is clicked. Dynamic controls must be created on every post back because that state is not maintained. Instead of just building the control in Button1 click, set a flag in Session so you know to rebuild it on Load too. So, in Button1_Click, at the very end of the method, add this line:
Session["BuildMyText"] = true;
and then in Page_Load:
if (Session["BuildMyText"] != null && (bool)Session["BuildMyText"])
{
// build the text box here too
}
and then finally, wrap the construction of the text box in the Button1_Click like this:
if (Session["BuildMyText"] != null && (bool)Session["BuildMyText"])
{
...
}
You need to recreate the control as below:
protected void Button2_Click(object sender, EventArgs e)
{
TextBox txt = new TextBox(); //add this line
TextBox txt = Panel1.FindControl("myText") as TextBox;
Response.Write(txt.Text);
}
Related
I am trying to store the text of the currently selected item of an Asp:Listbox in a variable. The value is always stored a null, or I receive the error
"System.NullReferenceException: 'Object reference not set to an instance of an object.'"
Listbox declaration below
<asp:ListBox ID="lbModules" runat="server" AutoPostBack="true" OnSelectedIndexChanged="lbModules_SelectedIndexChanged" ></asp:ListBox>
Code for SelectedIndexChanged below
`
protected void lbModules_SelectedIndexChanged(object sender, EventArgs e)
{
string code = lbModules.SelectedItem.Text;
int week = 1;
UpdateTextBox(week, code);
}
`
The listbox is being populated elsewhere with a method looping and adding values with listbox.items.add
I have tried
listbox.SelectedItem.Text, listbox.SelectedValue.Text, listbox.SelectedItem.Value, listbox.SelectedValue.Value,
Nothing I try returns the text of the selected value, always throws an exception or returns null.
Ok, first up, it does not make much sense to use the selected index change event UNLESS you have a autopostback=true.
So, if the user is to enter some info into text box etc., then the user say hits your submit button, then I not really sure of any value of using the selected index change event. But, with autopost-back it does.
hence, this markup:
<h2>Select Hotels</h2>
<asp:ListBox ID="ListBox1" runat="server" AutoPostBack="true"
DataValueField="ID"
DataTextField="HotelName"
OnSelectedIndexChanged="ListBox1_SelectedIndexChanged"
Width="190px" Height="160px" >
</asp:ListBox>
<h3>Selected value</h3>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
And code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL =
"SELECT ID,HotelName FROM tblHotelsA ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader());
ListBox1.DataSource = rstData;
ListBox1.DataBind();
}
}
}
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (ListBox1.SelectedIndex >= 0)
{
TextBox1.Text = ListBox1.SelectedItem.Value;
TextBox2.Text = ListBox1.SelectedItem.Text;
}
}
Note VERY but BEYOND careful that we ONLY load the listbox ONE time. Since for any event trigger on a page, the on-load event fires first, and THEN you code stub for the given button or event. Thus, if you load up the lb, or grid or in fact "any" data, but fail to include the all important if !IsPostBack code stub?
Then you cannot actually build a working web page!!! (so, my last 200+ web pages I have built ALL have and ALWAYS have that real first page load, since as noted, the on-load event triggers always on post-backs. So, if you load up the lb or anything again, it will blow out and overwrite your selections you have made).
So, above results in this:
However, if user is to enter data, select things, and THEN hit a submit button, then of course you probably would remove the autopostback = true. And place the above code behind the button click, and NOT use the selected index change event.
Even if you add items to the lb with code, the above rules still apply.
So, say this listbox:
<h2>Select Hotels</h2>
<asp:ListBox ID="ListBox1" runat="server" AutoPostBack="true"
OnSelectedIndexChanged="ListBox1_SelectedIndexChanged"
Width="190px" Height="160px" >
</asp:ListBox>
<h3>Selected value</h3>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
We still need the autopostback, and thus this code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
for (int i = 1; i <= 6; i++)
{
string MyText = "Item # " + i;
ListBox1.Items.Add(new ListItem(MyText, i.ToString()));
}
}
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (ListBox1.SelectedIndex >= 0)
{
TextBox1.Text = ListBox1.SelectedItem.Value;
TextBox2.Text = ListBox1.SelectedItem.Text;
}
}
And now we get/see this:
So, either you are missing autopostback, or you are re-running your code to fill the lb each time on post-back, and that will as noted blow out any selecting the user makes.
<asp:TextBox ID="TextBox2" AutoPostBack="true" runat="server" Width="415px" Height="50px" OnTextChanged="TextBox2_TextChanged"></asp:TextBox>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Save Changes" />
I'm attempting to save the data as such:
protected void TextBox2_TextChanged(object sender, EventArgs e)
{
Session["data"] = TextBox2.Text;
}
And retrieving:
protected void Button1_Click(object sender, EventArgs e)
{
string temp = (string)Session["data"];
}
When i print the string though, I am receiving a white space. Any help would be appreciated. Thanks in advance
In order to store data in Sesstion try something like:
protected void TextBox2_TextChanged(object sender, EventArgs e)
{
Session.Add("data", TextBox2.Text);
}
And no other changes in the retriving part.
As a usage I noticed that when focus is set to text box, the typing cursor is active in text box, the break point in the button's event handler is not hit when pressing the button, so this might be your non functional case.
To get this working after you finish typing into the text box, hit for instance the TAB key and then click on the button and the value from text box is retrived in button's click event handler.
I have a FormView with data(DataSource,DataBind) that I fill with value='<%# Eval("Name") %>' , but after I'm changing the text in TextBox and press update button I see the same value that before, I cant see new value that I have typed.
What I am missing here?
my html
<asp:FormView ID="MainFormTemplate" runat="server">
<ItemTemplate>
<li class="li_result" runat="server">
<div class="col-3">
<input id="txt_Name" runat="server" value='<%# Eval("Name") %>'>
</div>
</li>
</ItemTemplate>
</asp:FormView>
<asp:Button id="btn_Update" runat="server" OnClick="btn_Update_Click" Text="Update" />
Server side
protected void Page_Load(object sender, EventArgs e)
{
using (DB_MikaDataContext data = new DB_MikaDataContext())
{
MainFormTemplate.DataSource = data.File_Projects.Where(x => x.Num_Tik.Equals("12")).ToList();
MainFormTemplate.DataBind();
}
}
public void btn_Update_Click(object sender, EventArgs e)
{
//using System.Web.UI.HtmlControls
HtmlInputText twt = (HtmlInputText)MainFormTemplate.FindControl("txt_Name");
string text = twt.Value;//i see old value ,not new one that i typed in text box
}
In every postback, you are always getting the old value from your database. The solution is check if the page is being rendered for the first time (!IsPostBack) then set your MainFormTemplate's DataSource else if is being loaded in response to a postback (IsPostBack) get the txt_Name's value like this:
HtmlInputText twt;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
using (DB_MikaDataContext data = new DB_MikaDataContext())
{
MainFormTemplate.DataSource = data.File_Projects.Where(x => x.Num_Tik.Equals("12")).ToList();
MainFormTemplate.DataBind();
}
}
else
{
twt = MainFormTemplate.FindControl("txt_Name") as HtmlInputText;
}
}
protected void btn_Update_OnClick(object sender, EventArgs e)
{
string text = twt.Value; // You will get the new value
}
with Page_Load executing every postback, you are always writing value from database (?), and value sent from browser is lost (although still exist in Page.Request.Form member).
In ASP.NET, When a page is submitted, the Page_Load event runs before the button click event. So, the textbox value gets repopulated with its original value before the click event looks at that value.
If this is the situation, then you can wrap the code that assigns the value to the textbox in an if block like this:
if (!IsPostBack)
{
HtmlInputText twt = (HtmlInputText)MainFormTemplate.FindControl("txt_Name");
string text = twt.Value;
}
Hope this helps you.
I have a form like the following:
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="plcHolder" runat="server">
</asp:PlaceHolder>
<asp:Button ID="btnSubmit" Text="submit" runat="server"
onclick="btnSubmit_Click" />
</div>
</form>
And here is my code:
protected string FetchDataFromDatabase()
{
return "some long string";
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.plcHolder.Controls.Add(new Label() { Text = FetchDataFromDatabase() } );
}
}
Page_Load() gets a long string from the database.
protected void btnSubmit_Click(object sender, EventArgs e)
{
this.plcHolder.Controls.Add(new Label() { Text = "new text" });
}
My Button adds new text to my page. However, when I click the button, I only see the string "new text" but I was looking for both texts ("some long string new text") instead.
I don't want to call my database at every button click since the text already loaded to the page. How do I achieve this?
I know that this example seems a little weird, it's because I tried to give the minimal working example.
In the load, when you get the value from the database, store it in Session:
Session["textFromDatabase"] = GetTextFromDatabase();
and then leverage that value in both places. So if you were in the click you would say:
... Text = Session["textFromDatabase"] + " new text";
and now you can get the value from the database when it's not a post back, just once like you stated, but leverage it over and over.
And I'm pretty sure, based on what you said, this is the inverse of the condition you want, throw a ! in front of it:
if (Page.IsPostBack)
I have a TextBox control inside a panel and this panel is inside DataList ItemTemplate.
After firing the ItemCommand event, everything works fine except that the TextBox.Text property is always an empty string "" although there is some text in it.
I tried several ways but without success. I would really appreciate if someone can assist me with this. Simplified code is shown below.
Thank you!
ASPX page:
<asp:DataList ID="dlDataList" runat="server" onitemcommand="dlDataList_ItemCommand">
<ItemTemplate>
<asp:Panel ID="pnlReply" runat="server" Visible="False">
<asp:TextBox ID="txtTextBox" runat="server"></asp:TextBox><br />
<asp:LinkButton ID="lnkbtnSend" CommandName="Send" runat="server">Send</asp:LinkButton>
</asp:Panel><br />
<asp:LinkButton ID="OpenPanel" CommandName="OpenPanel" runat="server">Open panel</asp:LinkButton>
</ItemTemplate>
</asp:DataList>
</asp:Content>
ASPX.CS Page code behind
protected void Page_Load(object sender, EventArgs e)
{
FillDataList();
}
private void FillDataList()
{
List<string> list = new List<string>();
list.Add("First");
list.Add("Second");
list.Add("Third");
dlDataList.DataSource = list;
dlDataList.DataBind();
}
protected void dlDataList_ItemCommand(object source, DataListCommandEventArgs e)
{
if (e.CommandName == "OpenPanel")
{
Panel pnlReply = (Panel)e.Item.FindControl("pnlReply");
pnlReply.Visible = true;
}
if (e.CommandName == "Send")
{
TextBox txtTextBox = (TextBox)e.Item.FindControl("txtTextBox");
//I tried this way also..
//TextBox txtTextBox = (TextBox)e.item.FindControl("pnlReady").FindControl("txtTextBox");
Label1.Text = txtTextBox.Text;
}
}
Please use IsPostBack in page load event. Without it your FillDataList(); is executing on every postback and resetting your DataList.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
FillDataList();
}
}