Retrieving MasterPage textbox Control on a postback to another page - c#

I have spend two days trying to figure out the solution to this problem, even tried ExpertExchange and still I can't get a solution. I am a very novice programmer to ASP.Net (using C#) and I DON'T want to use a string/url post
I have a MasterPage of which has a textbox called tbSearchString. It is a simple box that a user can enter something and then it does a Postback to another page SearchResults.aspx So I also have other pages, like Default.aspx that uses the MasterPage.
I have tried nearly everything and have read nearly every post I could find on the net and no mater what the Variables are always Null.
I have use this code on the searchResults loadpage event and Every one of these variables are null, even though I enter a value in the page text box and click the button to postback to the SearchResults page, the only time it works is if I am on the searchResults page and submit.
SearchResults back end page
protected void Page_Load(object sender, EventArgs e)
{
TextBox SearchString;
TextBox SearchString2;
TextBox SearchString3;
TextBox SearchString5;
if (Page.PreviousPage != null) //This is true on every test
{
SearchString = (TextBox)Page.PreviousPage.Master.FindControl("tbSearchString");
SearchString2 = (TextBox)PreviousPage.Master.FindControl("tbSearchString");
SearchString3 = (TextBox)Master.FindControl("tbSearchString");
TextBox LoginControlx = (TextBox)PreviousPage.FindControl("Form1");
if (LoginControlx != null)
{
TextBox SearchString4 = (TextBox)LoginControlx.FindControl("tbSearchString");
}
}
MainWebsite.Master page Code
<asp:TextBox ID="tbSearchString" runat="server"></asp:TextBox>
<asp:Button ID="btnSearch1" runat="server" Text="Search" PostBackUrl="~/SearchResultRentalEquiptment.aspx" />
I don't have anything in the CS backend page
So on the Default.aspx page
nothing special Just the Masterpage and some text content, I enter some text in the textbox goes to the SearchResults page and I can not get the darn value from the Textbox control from the Default or any other page.
What say you wise ones?

how do you redirect your form to search result form? if you are using Response.redirect, the value under Page.PreviousPage.Master.FindControl will be null . Try to use Server.Transfer to see if it works.

Here's one way:
Assuming this is your Master Page code:
<asp:TextBox ID="searchbox" runat="server" /><br />
<asp:Button ID="sendSearch" runat="server" PostBackUrl="~/Results.aspx" Text="Search" />
At the end of the day, it's all about HTTP POST, so in the target page Results.aspx PageLoad:
protected void Page_Load(object sender, EventArgs e)
{
string _foo = Request.Form[this.Master.FindControl("searchbox").UniqueID];
}
Hth....

Check out Session. I use it all the time when I need to get data from one page to another. I'm not currently able to write out a full example for you, but off the top of my head the following should work:
//page1.aspx:
protected void btnSubmit_Click(object sender, EventArgs e)
{
string greetingString = "Hello";
Session["MyValue"] = greetingString;
Response.Redirect("page2.aspx");
}
//page2.aspx:
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(Session["MyValue"].ToString()); //prints "Hello"
}

Related

Cannot get new value of control in popup modal

Do web controls ever appear like you are changing their values but actually retain the previous value?
I created a pop-up modal for users to edit an item. When the user clicks edit on an item on the main page, the following sequence happens:
The item's ID is passed to the Page_Load event of the modal page, and is used to populate the page control's with the item's data.
The user changes a value in a control. Ex: Changes text in a TextBox contol.
The user clicks save, triggering the Click event which creates a DataTransferObject with the values in the textboxes, which will be stored.
However, on step 3, the control's new value (TextBox.Text) still holds the value that it orginially had, not the value the user put in.
Add.aspx:
<%# MasterType VirtualPath="../MasterPages/Popup.Master" %>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:TextBox ID="TextBoxDescription" runat="server"></asp:TextBox>
<telerik:RadButton ID="btnSave" runat="server" Text="Save" OnClick="btnSave_Click"/>
</asp:Content>
Add.aspx.cs
//Cannot access the new values here
protected void btnSave_Click(object sender, EventArgs e)
{
//This will print the new text on Create, but the old text on Edit
System.Diagnostics.Debug.WriteLine(TextBoxDescription.Text);
}
//works properly
protected void Page_Load(object sender, EventArgs e)
{
objIDParam = Convert.ToInt64(Request.QueryString["ObjectID"]);
editMode = (objIDParam != 0) ? true : false;
if(editMode)
PopulateFields(objID);
}
//works properly
private void PopulateFields(long objID)
{
MyObject obj = GetObjectByID(objID);
TextBoxDescription.Text = obj.Description;
}
It is worth noting that this popup page is used for both creating items AND editing items. Create works fine (i.e. The item isn't saved with all blanks, but rather the user input). Editing an item will properly pull all that data back in, and let the user edit the fields, however I can't access the changed values in my code.
You need to check for IsPostBack in the Page_Load method.
The Page_Load gets called before the btnSave_Click method, so the TextBoxDescription.Text is getting reset to obj.Description before the btn_Save method runs.
Try returning out of Page_Load if you're posting back:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
return;
objIDParam = Convert.ToInt64(Request.QueryString["ObjectID"]);
editMode = (objIDParam != 0) ? true : false;
if(editMode)
PopulateFields(objID);
}
Have a look at ASP.NET Page Life Cycle Overview for more info.

Setting ASP.NET Button attributes client side and read attribute value server side

How can I retrieve a Button custom attribute after the attribute value has been changed using javascript?
Example:
Asp file
<asp:Button ID="Button1" runat="server" Text="Button1" />
<asp:Button ID="Button2" runat="server" Text="Button2" OnClick="Button2_Click" />
<script type="text/javascript">
var btn1 = '#<% Button1.ClientID %>';
var btn2 = '#<% Button2.ClientID %>';
$(btn1).click(function(e) {
e.preventDefault();
$(btn2).attr("actIndex", "2");
});
</script>
CodeBehind file
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
Button2.Attributes.Add("actIndex","1");
}
protected void Button2_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
// this should be 2 if button1 has been clicked
string actIndex = btn.Attributes["actIndex"];
}
If I click Button1 then I click Button2 the actIndex value is still "1" but if I use page inspect the Button2 actIndex attribute is "2", somehow the attribute value is not passed to postBack action.
How can I solve this mystery?
I think the problem you have is because the attributes are not being posted back to have their information rebuilt server side.
The control's state is built server side and stored in the ViewState before it serves up the page. Then you modify the value using javascript which has no effect because that vaule is not being posted back to the server. On PostBack, the server rebuilds the control from the known ViewState which has the default value you originally assigned which is the value 1.
To get around this you need to store the value in some type of control (thinking a HiddenField control) that will get posted back to the server and then rebuild the attribute server side.
eg (semi pseudo code):
// In your javascript write to a hidden control
$("#yourHiddenFieldControlName").val("2");
// Then in your server side c# code you look for this value on post back and if found,
// assign it to you attribute
if (!string.IsNullOrEmpty(yourHiddenFieldControlName.Value))
{
Button2.Attributes["actIndex"] = yourHiddenFieldControlName.Value;
}
Your control needs to be handled manually if you are modifying it client side with javascript.
only form elements can actually postback data. The server side will take the postback data and load it into the form element provided that the runat=server is set.
in markup or html:
<input type="hidden" runat="server" ID="txtHiddenDestControl" />
javascript:
document.getElementById('<%= txtHiddenDestControl.ClientID %>').value = '1';
code behind:
string postedVal = txtHiddenDestControl.Value.ToString();
NO need for Javascript below code will work for you
protected void Page_Load(object sender, EventArgs e)
{
Button2.Attributes.Add("actIndex", "1");
}
protected void Button1_Click(object sender, EventArgs e)
{
string Value = Button2.Attributes["actIndex"].ToString();//1
Button2.Attributes.Remove("actIndex");
Button2.Attributes.Add("actIndex", "2");
Value = Button2.Attributes["actIndex"].ToString();//2
}

ASP.NET Session State & Postback problems

I have a problem that I believe is a session state issue, but I'm at a loss to figure out what's wrong. I have a sample project to illustrate the problem. (Code below) I have 2 buttons. Each populates a List with some unique data and then uses that data to add a row to a table. The row contains text boxes so that the user can edit the data. (For my sample, there's no update button to persist the data.) To reproduce the problem in VS2010, create a new "ASP.NET Web Application" project and copy/paste the aspx code and the c# code-behind into Default.aspx, then run the application.
Press the DataSet 1 button and the grid should populate with 1 row.
Edit the data in one of the text boxes and tab off of the text box. (The newly entered text should remian, and the font should be blue. This is what I want to happen.)
Now click either of the DataSet buttons to reset the List and refresh the table.
Edit the data in one of the text boxes and tab off the text box. (Immediately, the text in the box refreshes back to its original value. This only happens once, though. If you edit either text box now, it will work normally.)
This is repeatable... the first edit after pressing the DataSet buttons a 2nd, 3rd, etc. time gets reset back to the original value. And I can't figure out why.
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="DebugPostbackIssue._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
Welcome to ASP.NET!
</h2>
<p>
Populate the table with DataSet #1:<asp:Button runat="server" ID="btnDS1" Text="Dataset 1" OnClick="btnDS1_Click" />
</p>
<p>
Populate the table with DataSet #2:<asp:Button runat="server" ID="btnDS2" Text="Dataset 2" OnClick="btnDS2_Click" />
</p>
<p>
<asp:Table runat="server" ID="tblData">
<asp:TableHeaderRow runat="server" ID="thrData">
<asp:TableHeaderCell Scope="Column" Text="Column 1"></asp:TableHeaderCell>
<asp:TableHeaderCell Scope="Column" Text="Column 2"></asp:TableHeaderCell>
</asp:TableHeaderRow>
</asp:Table>
</p>
</asp:Content>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace DebugPostbackIssue
{
public partial class _Default : System.Web.UI.Page
{
private List<string> _MyData = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Page_Init(object sender, EventArgs e)
{
LoadSessionData();
GenerateGrid(false);
}
protected void btnDS1_Click(object sender, EventArgs e)
{
_MyData = new List<string>();
_MyData.Add("111");
_MyData.Add("aaa");
SaveSessionData();
GenerateGrid(true);
}
protected void btnDS2_Click(object sender, EventArgs e)
{
_MyData = new List<string>();
_MyData.Add("222");
_MyData.Add("bbb");
SaveSessionData();
GenerateGrid(true);
}
private void SaveSessionData()
{
Session["MyData"] = _MyData;
}
private void LoadSessionData()
{
if (Session["MyData"] != null)
_MyData = (List<string>)Session["MyData"];
else
_MyData = new List<string>();
}
private void GenerateGrid(bool ClearData)
{
if (ClearData)
while (tblData.Rows.Count > 1)
tblData.Rows.Remove(tblData.Rows[tblData.Rows.Count - 1]);
TableRow tr = new TableRow();
foreach (string s in _MyData)
{
TableCell tc = new TableCell();
TextBox txtBox = new TextBox();
txtBox.Text = s;
txtBox.Attributes.Add("OriginalValue", s);
txtBox.TextChanged += new EventHandler(txtBox_TextChanged);
txtBox.AutoPostBack = true;
tc.Controls.Add(txtBox);
tr.Cells.Add(tc);
}
if (tr.Cells.Count > 0)
tblData.Rows.Add(tr);
}
void txtBox_TextChanged(object sender, EventArgs e)
{
TextBox Sender = (TextBox)sender;
if (Sender.Text == Sender.Attributes["OriginalValue"])
Sender.ForeColor = System.Drawing.Color.Black;
else
Sender.ForeColor = System.Drawing.Color.Blue;
}
}
}
Hi I took some time off of my work to compile your code, and I figured it out, just change your textbox change to the following :
void txtBox_TextChanged(object sender, EventArgs e)
{
TextBox Sender = (TextBox)sender;
if (Sender.Text == Sender.Attributes["OriginalValue"])
Sender.ForeColor = System.Drawing.Color.Black;
else
{
Sender.ForeColor = System.Drawing.Color.Blue;
if (Session["MyData"] != null)
{
List<string> _ss = (List<string>)Session["MyData"];
//_ss.Find(a => a == Sender.Attributes["OriginalValue"]);
_ss.Remove(Sender.Attributes["OriginalValue"]);
_ss.Add(Sender.Text);
}
}
}
ur welcome!
Try creating a datatable. I would, on "event" copy your asp table content to a datatable, then when you get the servers response add that to the datatable. Then copy the datatable back to your asp table, and repeat... Datatables can be used like variables.
Or try using a cookie.
Try changing...
protected void Page_Init(object sender, EventArgs e)
{
LoadSessionData();
GenerateGrid(false);
}
To...
protected override void OnLoadComplete(EventArgs e)
{
LoadSessionData();
GenerateGrid(false);
}
Based on your description I believe that your value is getting reset because of how the page life cycle works in ASP.NET & that is the page_init is getting called before your event due to ASP.NET quirkiness. Above code is how I work around it, I'm sure there's other ways too.
Okay, I have it working, now. Wizpert's answer pointed me in the right direction... Upon discovering that the TextChanged event did not fire during the times when the value was erroneously being reset to the original value, it occurred to me that during the Click events I was calling GenerateGrid(true). This forced the removal of the existing rows and the addition of new rows. (Removing & adding the dynamic controls at that point in the life cycle must be interfering with the TextChange event handler.) Since the Click event fires after Page Init and after Page Load, the state values were already written to the text boxes and I was overwriting them. But the 2nd text box edit did not force GenerateGrid(true) to be called so the state values were not overwritten any more.
If this sounds confusing, I apologize. I'm still wrapping my head around this. But suffice to say that I had to change my GenerateGrid method to reuse any existing rows and not delete them. (If they don't exist, like when GenerateGrid is called from Page Init, then they are added.) So this was a page lifecycle issue after all.
Thank you.

Manually bind a row in a repeater, to avoid losing viewstate data

I'm working on a page that uses a repeater to display a list of custom controls, each containing two dropdown lists.
On a click on the Add control button, the page adds a new row on the repeater, and a click on one of the Delete control buttons embedded in each control removes the relevant control from the repeater.
The delete part seems to work, (setting NamingController.Visible to false), but the add part fails, as once I add the new control, a call to a new repeater.DataBind() loses all viewstate data, preventing the dropdownlists from retrieving the values they had before postback.
Is there a way to manually bind the added control to the repeater without calling a full databind ? Or is there any other way to add a control without losing data ?
Here's some code (I only left what seems relevant, please let me know if you think I forgot to specify something) :
Page.aspx:
<asp:Button ID="addControl" runat="server" Text="Add control" />
<asp:Repeater ID="repeater" runat="server" OnItemDataBound="repeater_ItemDataBound">
<ItemTemplate>
<uc:CustomControlWithDropDownLists ID="custom" runat="server" />
</ItemTemplate>
</asp:Repeater>
Page.aspx.cs:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
repeater.DataSource = GetDataSource();
repeater.DataBind();
}
protected void Page_Init(object sender, EventArgs e)
{
addControl.Click += (sndr, args) =>
{
// Create the object we want to bind to the repeater
ObjectToBind objectToBind = new ObjectToBind();
// Here is what causes data loss
((IList<ObjectToBind>)repeater.DataSource).Add(objectToBind);
repeater.DataBind();
};
}
protected void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// Do some stuff
}
}
CustomControlWithDropDownLists.ascx:
<%-- Some dropdown lists --%>
<asp:Button ID="deleteControl" runat="server" Text="Delete control" />
CustomControlWithDropDownLists.ascx.cs:
protected void Page_Init(object sender, EventArgs e)
{
deleteControl.Click += (sndr, args) =>
{
// ... Delete the control ...
((Button)sndr).NamingContainer.Visible = false;
};
}
You are loosing the data because of View state.
View State losses the data when we are redirecting to the another page.
View state only store the data for the specific page.
The moment you go to another page data is lost by view state.
& there are many chances of losing the data on the same page because of many reasons.
So, the best way to store the data is to use session variable.
Session stores the data even when you are redirecting to the another page.
It is the best way to store the data.
By default it stores the data for 20 minutes.
I hope this will solve your issue.
I had done something similar in the past and found this link from c-sharp corner helpful.
http://www.c-sharpcorner.com/Blogs/10913/add-dynamic-row-using-repeater.aspx
The key element for me if memory servers is using the ViewState object and binding accordingly.
myObject = ViewState["MyData"]; etc.
( I am sorry I don't have access to my code at the moment )

Add value to box and refresh using Javascript. Then get value in code-behind

I have an aspx page that has a textbox. The user opens a modal window in this page to do a search and selects an item. When selected the value is passed into a textbox in the aspx page and then refreshes.
What I then want to do is get the value in the textbox after refresh. In my code-behind it hits the page load with is fine but the value is always "" rather than the text inside it.
How can I go about getting the value after the JS has refreshed that page? Is it a matter of adding it into the right part of the page lifecyle?
Please note that the modal window does not return the value through querystring, it does it by setting the value of the box in the parent:
window.top.document.getElementById('txtCustomerType').value = value;
Then does a refresh:
window.parent.location.reload();
This is the code that I use to test what the value is after refresh (page load):
protected void Page_Load(object sender, EventArgs e)
{
string test;
test = txtCustomerType.Text;
}
But the value of txtcustomertype.text comes out as "" even though it has a value.
If you refresh your page, surely the textbox value will be clear.
So i think you need to use hidden field or remove the window.parent.location.reload();
Update
protected void Page_Load(object sender, EventArgs e)
{
string test;
test = txtCustomerType.Text;
}
When you reload the page, The textbox value should be there at this time because it's a old textbox value, but any values not will assign in page load for new load . SO the textbox was refresh (reload) on end of the load event.
So you should need this way
protected void Page_Load(object sender, EventArgs e)
{
string test;
test = txtCustomerType.Text;
txtCustomerType.Text=txtCustomerType.Text
}
In above code will assign the old textbox value to second time.
If you use runat server in your textbox, then you need to clientId for read a textbox in javascript

Categories