How to keep the variable value after post back - asp.net

I am trying to keep the variable value after the post back. I tried it both by session variable and also Viewstate but failed to keep the value of random number same. Every time after button press (after page refresh) I am getting a new random value but I want to keep the same value.
//in code behind
public static int RandNumber{ get; set; }
protected void Page_Load(object sender, EventArgs e)
{
//by using session
Session["rand"] = rnd.Next(0, 10);
RandNumber = Int32.Parse(Session["rand"].ToString());
//by view state
int rand = rnd.Next(0, 10);
ViewState["KEY"] = rand;
RandNumber = Int32.Parse(ViewState["KEY"].ToString());
}
for post back in the form:
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
And tried to access in the page as below:
<p>Random No: <%= RandNumber %></p>

Only set a new random number if it's not a post back by checking IsPostBack
public int RandNumber{ get; set; }
protected void Page_Load(object sender, EventArgs e)
{
//by using session
if(!IsPostBack){
Session["rand"] = rnd.Next(0, 10);
}
RandNumber = Int32.Parse(Session["rand"].ToString());
}

Related

CheckBox on a GridView

I have a grid view that has 3 columns(Name, Address, Status) and a checkbox.The Status has 3 properties, Active, Pending, and Disabled. The page load all the information from the database. When loading the page, only accounts that are ACTIVE should be displayed (and the checkbox should remain unchecked)
When clicking the checkbox, the page should load the DISABLED, along with the accounts already displayed When the page loads for the first time.
Aspx:
<asp:CheckBox ID="ChkBox1" runat="server" AutoPostBack="true" OnCheckedChanged="cbShowAllColumn_Changed" TextAlign="Right" Text="Show All"/>
</asp:Panel>
Code behind:
protected void cbShowColumn_Changed(object sender, EventArgs e)
{
string columnName = (sender as CheckBox).ID.Substring(1);
gvTest.Columns[(int)Enum.Parse(typeof(AccountColumns), columnName)].Visible = (sender as CheckBox).Checked;
}
protected void cbShowAllColumn_Changed(object sender, EventArgs e)
{
bool _checked = (sender as CheckBox).Checked;
foreach (Control ctrl in pAccount.Controls)
if (ctrl is CheckBox)
{
(ctrl as CheckBox).Checked = _checked;
gvMain.Columns[(int)Enum.Parse(typeof(AccountColumns), (ctrl as CheckBox).ID.Substring(2))].Visible = _checked;
}
}
I compiled a small asp .net page to do what you asked.
Note: In your project, you should probably take the "source" out of the BindGrid method, so that you don't "get" the data from scratch every time the page is posted back to. I did it that way because I used an anonymous type.
Note #2 I converted an int to your enum and then to a string. Since you use real data you should handle that differently, by using the enum itself.
Markup:
<asp:CheckBox ID="ChkBox1" runat="server" AutoPostBack="true" OnCheckedChanged="cbShowAllColumn_Changed" TextAlign="Right" Text="Show All"/>
<br/>
<asp:gridview ID="gvMain" runat="server" >
</asp:gridview>
Codebehind:
protected void Page_Load(object sender, EventArgs e)
{
BindGrid(false);
}
private void BindGrid(bool showActiveOnly)
{
var source = Enumerable.Range(1, 10)
.Select(number => new { number, status = (Enum.ToObject(typeof(Statuses), number % 3)).ToString() });
var filteredSource = source.Where(x => x.status == "Active" || !showActiveOnly);
gvMain.DataSource = filteredSource;
gvMain.DataBind();
}
protected void cbShowAllColumn_Changed(object sender, EventArgs e)
{
bool _checked = (sender as CheckBox).Checked;
BindGrid(_checked);
}
private enum Statuses
{
Active,
Pending,
Disabled
}

Preserving user control on autopostback asp.net

I have two user controls: dsucTopLeft and dsucTopRight in an aspx page. Each of the user controls has a dropdownlist to select values from.
The aspx page has a button "Save".
In the OnClickEvent of the button, I take data from those user controls (which return the values from the drop down list). I need to insert these values into database. However, these values set to 0 after the button is clicked.
How would I preserve those values?
Code:
ParentTemplate.aspx
<div class="leftDashboard">
<uc:dsuc ID="dsucTopLeft" runat="server" />
</div>
<div id="rightDashboard">
<uc:dsuc ID="dsucTopRight" runat="server" />
</div>
It also has a button:
<asp:Button ID="SaveButton" runat="server" OnClick="SaveButton_Click" Text="Save Dashboard" />
This is the codebehind for the button:
protected void SaveButton_Click(object sender, EventArgs e)
{
//If the mode is "CREATE", then it needs to insert the information about dashboard and the charts it contains
for (int i = 0; i < dsuc.Length; i++)
{
dsuc[i].dashboardId = dashboardId;
if (dsuc[i].chartId != 0) //Here, the chartId remains 0
dsuc[i].insert();
}
}
dsuc is an array. It is being populated in the following way:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
dsuc[0]=dsucTopLeft;
dsuc[1]=dsucTopRight;
}
}
UserControl:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
initializeDropDownList();//It initializes the drop down list
}
}
public void insert()
{
//It inserts into database
}
protected void chartDDLSelectedIndexChanged(object sender, EventArgs e)
{
oldChartId = chartId;
String chartTitle = chartDropDownList.SelectedItem.Text;
if (chartTitle != dropDownMessage)
{
chartId = int.Parse(chartDropDownList.SelectedItem.Value);
//Chart user control should be retrieved from the database and drawn.
chartTitleLabel.Text += "chart id : " + chartId.ToString() + " title: " + chartTitle;
//chartUserControl.Visible = true;
}
}
The user control i.e. the class of dsuc[] changes its chartId when an item in its drop down list is selected. I printed the value, it works. But that same value becomes 0 when the button in clicked.
Remove the if (!Page.IsPostBack)from
if (!Page.IsPostBack)
{
dsuc[0]=dsucTopLeft;
dsuc[1]=dsucTopRight;
}
If not, it will only populate it when is not post back. As a click produces a post back, you'll want that code being executed :)
Also, it is probably that your clickp event is being called beforeselectedindexchanged`. In that case, the code that sets chartId is not executed (yet) when the click event is fired. You can solve that doing this:
public int ChartId { get { return int.Parse(chartDropDownList.SelectedItem.Value); }}
and calling that property instead. Also, you can use that property in your selectedindexchanged event handler

Is it possible to pass an object to usercontrol in front-end?

Is there anyway to pass an object to an usercontrol through the frontend tags? I have tried the following but it doesn't work.
Backend
public Range Range { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
// Popular channel range
Range Range = new Range()
{
Min = 0,
Max = 8
};
}
Frontend
<uc:PopularItems Range="<%=Range %>" runat="server" />
You can't use <%= with a server control. You should use <%# and databind:
Backend
[Bindable(true)]
public Range Range { get; set; }
Frontend
<uc:PopularItems ID="myControl" Range="<%# Range %>" runat="server" />
Backend of the page
if(! IsPostBack) {
myControl.DataBind();
// or, to bind each control in the page:
// this.DataBind();
}

asp.net web forms best practice to retrieve dynamic server control values

I populate web form with dynamic list of exams from database. I want user to enter examination marks for each exam. There is list of exam titles and textbox near each title.
I create list with repeater control (ViewState is disabled) :
<asp:Repeater ID="rptExams" runat="server" onitemdatabound="rptExams_ItemDataBound" >
<ItemTemplate>
<tr>
<td>
<asp:Literal runat="server" ID="ltTitle"/>
</td>
<td>
<asp:HiddenField runat="server" ID="hfId"/>
<asp:Textbox runat="server" ID="tbMark"/>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
And bind data to repeater on page_init:
class Exam
{
public int Id { get; set;}
public string Title { get; set;}
}
...
// this list is retrieved from database actually
Exam[] Exams = new Exam[]
{
new Exam { Id = 1, Title = "Math"},
new Exam { Id = 2, Title = "History"}
};
...
protected void Page_Init(object sender, EventArgs e)
{
rptExams.DataSource = Exams;
rptExams.DataBind();
}
So far so good. Then I have to retrieve data on postback. I have two ways but both of them looks ugly.
Idea is to store dynamically created databounded controls on ItemDataBoundEvent in Page_Init stage, and process their values in Page_Load stage. It looks like this:
private Dictionary<HiddenField, TextBox> Id2Mark = new Dictionary<HiddenField, TextBox>();
protected void rptExams_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
...
if (IsPostBack)
{
var tbMark = (TextBox)e.Item.FindControl("tbMark");
var hfId = (HiddenField)e.Item.FindControl("hfId");
// store dynamically created controls
Id2Mark.Add(hfId, tbMark);
}
...
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
foreach (var pair in Id2Mark)
{
int examId = Int32.Parse(pair.Key.Value);
string mark = pair.Value.Text;
// PROCESS
}
...
I'm completely sure there is a better way to retrieve data from dynamically created controls. Thank you in advance!
Here's how you can do it:
First, don't rebind the data on postback - it's not necessary. Only bind it on the first call of the page.
protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack){
rptExams.DataSource = Exams;
rptExams.DataBind();
}
}
You won't need the Dictionary neither.
Then, on a postback, you can get to the bound data as follows:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
foreach (RepeaterItem item in rptExams.Items)
{
HiddenField hfId = item.FindControl("hfId") as HiddenField;
TextBox tbMark = item.FindControl("tbMark") as TextBox;
int examId = Int32.Parse(hfId);
string mark = tbMark.Text;
// PROCESS
}
}
}

Paging ObjectDataSource

My ASP page code:
<asp:ObjectDataSource runat="server" ID="odsResults" OnSelecting="odsResults_Selecting" />
<tr><td>
<wssawc:SPGridViewPager ID="sgvpPagerTop" runat="server" GridViewId="sgvConversionResults" />
</td></tr>
<tr>
<td colspan="2" class="ms-vb">
<wssawc:SPGridView
runat="server"
ID="sgvConversionResults"
AutoGenerateColumns="false"
RowStyle-CssClass=""
AlternatingRowStyle-CssClass="ms-alternating"
/>
</td>
</tr>
Class code:
public partial class Convert : System.Web.UI.Page
{
...
private DataTable resultDataSource = new DataTable();
...
protected void Page_Init(object sender, EventArgs e)
{
...
resultDataSource.Columns.Add("Column1");
resultDataSource.Columns.Add("Column2");
resultDataSource.Columns.Add("Column3");
resultDataSource.Columns.Add("Column4");
...
odsResults.TypeName = GetType().AssemblyQualifiedName;
odsResults.SelectMethod = "SelectData";
odsResults.SelectCountMethod = "GetRecordCount";
odsResults.EnablePaging = true;
sgvConversionResults.DataSourceID = odsResults.ID;
ConversionResultsCreateColumns();
sgvConversionResults.AllowPaging = true;
...
}
protected void btnBTN_Click(object sender, EventArgs e)
{
// add rows into resultDataSource
}
public DataTable SelectData(DataTable ds,int startRowIndex,int maximumRows)
{
DataTable dt = new DataTable();
dt.Columns.Add("Column1");
dt.Columns.Add("Column2");
dt.Columns.Add("Column3");
dt.Columns.Add("Column4");
for (int i =startRowIndex; i<startRowIndex+10 ;i++)
{
if (i<ds.Rows.Count)
{
dt.Rows.Add(ds.Rows[i][0].ToString(), ds.Rows[i][1].ToString(),
ds.Rows[i][2].ToString(), ds.Rows[i][3].ToString());
}
}
return dt;
}
public int GetRecordCount(DataTable ds)
{
return ds.Rows.Count;
}
protected void odsResults_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["ds"] = resultDataSource;
}
}
On clicking the button resultDataSource receives some rows. Page reload and we can see result in sgvConversionResults. First 10 rows. But after click next page in pager we have message "There are no items to show in this view". When I try debug I find that after postBack page (on click next page) input params "ds" is blank, ds.Rows.Count = 0 and etc... As though resultDataSource became empty((
What did I do incorrectly?
onPostBack all variables get default values, sgvConversionResults save her structure but has clear rows. How I can save sgvConversionResults data onPostBack event???
Maybe try:
protected void Page_Load(object sender, EventArgs e)
{
sgvConversionResults.DataBind();
}
Your code seems a bit convoluted though, any particular reason you are using an ObjectDataSource? Cause you can bind the datatable directly to the gridview in the codebehind
I transmit resultDataSource with ViewState and this work success!

Resources