Listview databind causes lost of formview Data - c#

within my code , after a research via a Formview , I need to call the listview.databind and this makes impossible to get the Formview data , even if in the screen they still appear .
this is my code
protected void DemandeSearchFormView_ItemInserting(object sender, FormViewInsertEventArgs e)
{
ListView listview = (ListView)panelPagination.FindControl("listdeclarations");
ViewState["search"] = "search";
listview.DataBind();
}
the databind() normally call this method
public DeclarationGeneraleBean RechercheByCritere()
{
DeclarationGeneraleBean declarationBean = new
DeclarationGeneraleBean();
declarationBean.IdService = (int) Session["idService"];
if (ViewState["search"] != null)
{
TextBox numOrdre =
(TextBox)DemandeSearchFormView.FindControl("numtxt");
}
the ViewState["search"] is null , I dont know why ?? it seems that the databind() recharge the page or something like this .
Have any one an idea how to deal with this ?

Do you set the viewstate in your page load event?
If yes, i think you should add a condition in your Page_Load event :
private void Page_Load()
{
if (!IsPostBack)
{
}
}
it prevent the data to be reloaded on this event, if a post is submited.

Related

Dropdown list binding issue in asp.net

I have a placeholder which has some dropdownlist and a button, now this placeholder is initially hidden and when user makes any search on the page, based on that the placeholder gets visible and the dropdownlist gets filled, this is working absolutely fineNow the problem starts when i click on the button inside the placeholder (next to dropdownlist), at this point of time, all the dropdownlist gets blank. I understand first page load executes and because there are no bindings (as dropdowns are binded on search click) it would make it blank, but i am not getting once the dropdown has been binded why it would matter for the page load to unbind it. Here's my code:
Page Load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
plcView.Visible = false;
}
}
Search Button Click:
protected void btnSearch_Click(object sender, EventArgs e)
{
try
{
if (!AppGlobal.IsSanadCompleted(AppGlobal.Sanads.Amma, txtITSId.Text))
{
lblErrorMessage.CssClass = "dnnFormMessage dnnFormWarning";
lblErrorMessage.Text = "You need Amma Sanad to attempt for Hifz Program.";
plcView.Visible = false;
}
else
{
plcView.Visible = true;
txtJuz.Text = (Hifz.GetLastJuzAttempted(txtITSId.Text) + 1).ToString();
drpAyahFrom.DataTextField = "Key";
drpAyahFrom.DataValueField = "Value";
drpAyahFrom.DataSource = objHifz.GetAyahListForHifzProgram(Convert.ToInt32(txtJuz.Text));
drpAyahFrom.DataBind();
drpAyahTo.DataTextField = "Key";
drpAyahTo.DataValueField = "Value";
drpAyahTo.DataSource = objHifz.GetAyahListForHifzProgram(Convert.ToInt32(txtJuz.Text));
drpAyahTo.DataBind();
drpGrade.DataSource = AppGlobal.GetGrades();
drpGrade.DataBind();
}
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
}
I even tried enabling EnableViewstate at page and also at skin (I am using Dotnetnuke) level, but still it does not makes any difference.
Can anyone please suggest where i would be getting wrong.
DotNetNuke is nothing but an ASP.Net app. So to look into your issue we have to delve into the Page Life-Cycle of an ASP.Net page. There you will notice a Page_Event called SaveStateComplete. You see, this is called just before the Render event(At this event the page is displayed to the end user). So any changes done after rendering the page will not be saved in to the ViewState by default. Since your DropDowns are blank during SaveStateComplete, after a PostBack you're getting empty DropDowns.
The solution is to forcefully save the DataSource in your custom ViewState. For ex. in your button click, add the following:
var obj = objHifz.GetAyahListForHifzProgram(Convert.ToInt32(txtJuz.Text)));
drpAyahFrom.DataSource = obj;
ViewState["myUniqueKey"] = obj;
Then at the Page_Load event, you can use:
if (!IsPostBack)
{
plcView.Visible = false;
}
else
{
if(ViewState["myUniqueKey"] != null)
{
drpAyahFrom.DataTextField = "Key";
drpAyahFrom.DataValueField = "Value";
drpAyahFrom.DataSource = ViewState["myUniqueKey"];
drpAyahFrom.DataBind();
}
}
You may have to perform the casting as per the requirement.

Overriding the Telerik RadGrid AddNewRecordButton functionality to redirect the user to a new page rather than add a new insert record row to the grid

Previously when my RadGrid was not a batch edit grid I was able to use the grid's AddNewRecord button to redirect the user to another page with the following code:
protected void RadGrid1_ItemCommand(object sender, GridCommandEventArgs e)
{
if (e.CommandName == "InitInsert")
{
Response.Redirect(redirectUrl + "?ProductID=" + this.ProductId);
}
}
After I made my grid a batch edit grid the Add New Button doesn't go into the ItemCommand event anymore and instead tries adding an inline insert record row to the grid. Is there anyway I can still use this button and override its functionality to still redirect the user?
So I've tested this and confirmed what I suspected in the comments. When EditMode="Batch", the "Add New Record" button, along with others, no longer cause a postback. You can override this by removing the JavaScript of the OnClientClick in the RadGrid1_ItemCreated like so:
Add this to your RadGrid1 attributes:
OnItemCreated="RadGrid1_ItemCreated"
Code behind (note: there is actually a Button AND a LinkButton):
protected void RadGrid1_ItemCreated(object sender, Telerik.Web.UI.GridItemEventArgs e)
{
if (e.Item.ItemType == Telerik.Web.UI.GridItemType.CommandItem) {
//This is the icon with the plus (+) sign unless you've changed the icon
Button iconButton = e.Item.FindControl("AddNewRecordButton");
if (iconButton != null) {
iconButton.OnClientClick = "";
}
//This is the words "Add New Record" or whatever you've called it
LinkButton wordButton = e.Item.FindControl("InitInsertButton");
if (wordButton != null) {
wordButton.OnClientClick = "";
}
}
}
This should allow the postback to happen and the code you posted should be able to run.

ASP.Net: GridView control and combobox woes

I've got a GridView control and Combobox control that are both successfully populated in my Page_Load event (within a block that checks for IsPostBack == false).
I've got an empty button 'btnClick' event handler which will reload the page when clicked. Both the GridView and Combobox controls have their EnableViewState property set to True. The behaviour I was expecting and hoping for was:
Page will reload with the GridView control still populated.
Page will reload with Combobox still populated and the item selected by the user still set as the selected item.
Unfortunately, the behaviour I'm getting is as follows:
GridView control is now empty and shows no data.
Combobox is now empty.
Code as follows:
public MyPage()
{
this.Load += new EventHandler(Page_Load);
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
DataAccessObj daObj = new DataAccessObj();
foreach (DataRow dataRow in daObj.GetAllData())
{
ListItem listItem = new ListItem(dataRow.ToString(), dataRow.Id.ToString());
myCombobox.Items.Add(listItem);
}
IncidentGrid.DataSource = daObj.GetIncidentsByReportedById(0);
IncidentGrid.DataBind();
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
// Do nothing
}
What I would like to do is allow the user to select an item from the Combobox. Upon clicking Submit, the GridView would be repopulated (based upon the selected item). The Combobox will remain populated and show the last selected item.
Can someone help explain where I might be going wrong? TIA
When you click your button, the page is posted back, in your page load, if it is a postback you need to databind the grid appropriately you need to add a condition to your page load event like
Firstly on your btn_click, you need to store the id selected with something like:
if (myCombobox.SelectedItem != null)
{
if (int.TryParse(myCombobox.SelectedItem.Value, out reportedById) == false)
{
reportedById = 0;
ViewState["reportedById"] = reportedById; // Need to remember which one was selected
}
}
Then On your Post Back
else (IsPostBack)
{
if (ViewState["reportedById"]) != null)
{
IncidentGrid.DataSource = daObj.GetIncidentsByReportedById(Convert.ToInt32(ViewState["reportedById"]));
IncidentGrid.DataBind();
myCombobox.SelectedItem.Value = ViewState["reportedById"].ToString(); // set combo
}
else
{
IncidentGrid.DataSource = daObj.GetIncidentsByReportedById(0);
IncidentGrid.DataBind();
}
}

ASP.NET ListView-embedded Web-Control loses state and passed-values on ItemDataBound event handler when page posts back

This question is about a very strange behavior of web controls. Consider the following please.
Scenario
I have a web control which is used to show some data. MyWebControl.ascx file is the following:
<%# Control ViewStateMode="Enabled"
Language="C#"
AutoEventWireup="true"
CodeFile="MyWebControl.ascx.cs"
Inherits="MyWebControl" %>
<div>
<asp:Label ID="MyLabel1" runat="server"></asp:Label>
<asp:Label ID="MyLabel2" runat="server"></asp:Label>
</div>
And code behind MyWebControl.ascx.cs is:
public partial class MyWebControl :
System.Web.UI.UserControl {
protected string str1;
protected string str2;
public string Str1 {
get { return this.str1; }
set { this.str1 = value; }
}
public string Str2 {
get { return this.str2; }
set { this.str2 = value; }
}
protected void Page_Load(object sender, EventArgs e) {
this.MyLabel1.Text = this.str1;
this.MyLabel2.Text = this.str2;
}
}
Well, I use this control inside a ListView of mine in an ordinary web form. This web form is called Default.aspx and, following, I am showing a slice of its code, only the one where the ListView resides in:
<%# Page Title="My page" Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%# Register TagPrefix="my" TagName="MyWC" Src="~/MyWebControl.ascx" %>
...
...
<div>
<asp:ListView ID="MyLV_ListView" runat="server"
EnableViewState="true"
OnPreRender="MyLV_ListView_PreRender"
OnItemDataBound="MyLV_ListView_ItemDataBound">
<ItemTemplate>
<my:MyWC ID="WC_MyWC" runat="server" />
</ItemTemplate>
</asp:ListView>
</div>
This web form code-behind Default.aspx.cs is:
public partial class _Default : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
if (!this.IsPostBack) {
DAO d = new DAO(...); /* This object will contain some data */
/* Data are somehow paged, changing index, we have other data */
/* Please do not worry about paging, it works, problem is another */
d.PageIndex = 0;
this.ViewState["DAO"] = d; /* DAO is serializable */
this.ViewState["PageIndex"] = 0;
Data[] data = d.GetData(); /* Returns an array of objects representing my data */
/* Custom way of storing data in objects */
/* GetData use the PageIndex to get only a range of results */
this.MyLV_ListView.DataSource = data;
this.MyLV_ListView.DataBind();
}
}
protected void MyLV_ListView_ItemDataBound(object sender, ListViewItemEventArgs e) {
if (e.Item.ItemType == ListViewItemType.DataItem) {
((MyWebControl)e.Item.FindControl("WC_MyWC")).Str1 =
((Data)e.Item.DataItem).DataField1;
((MyWebControl)e.Item.FindControl("WC_MyWC")).Str2 =
((Data)e.Item.DataItem).DataField2;
}
}
protected void MyLV_ListView_PreRender(object sender, EventArgs e) {
if (this.IsPostBack)
this.MyLV_ListView.DataBind();
}
// A TreeView will cause the page to reload,
// this is the handler called when a tree node is
// selected, the node is used to change the page
// for showing data in my listview.
protected void MyLVPaging_TreeView_SelectedNodeChanged(object sender, EventArgs e) {
this.ViewState["PageIndex"] = int.Parse(this.MyLVPaging_TreeView.SelectedNode.Value);
((DAO)this.ViewState["DAO"]).PageIndex = (int)this.ViewState["PageIndex"];
// After setting the new index, GetData will return another set of results
this.MyLV_ListView.DataSource = ((DAO)this.ViewState["DAO"]).GetData();
}
}
The problem
What is my problem???
Well, when the page loads for the first time I can see some data in the list view, so everything works.
When I select another page, I cause the page to reload and post back... my ListView will show the correct number of entries but with no data in it. The web control is placed as many times as the number of retrieved data records, but the web control has no data in it.
Debugging results
I conducted some debug sessions and this is what happens, please follow me, this is VERY IMPORTANT to understand I guess.
Page loads for the first time
1) Load page method is executed.
2) ListView's ItemDataBound event handler is executed. Well, given that I have three elements in the Data[] array in the DataSource, the handler is called three times. Inspecting values when proceeding debugging the method, I can see that ((Data)e.Item.DataItem).DataField1 and ((Data)e.Item.DataItem).DataField2 are the correct values retrieved from the bound data source in the ListView.
After the method is executed, the debugger cursor moves to MyWebControl.ascx.cs to the control's Page_Load method. I can see, inspecting variables, that this happens:
protected void Page_Load(object sender, EventArgs e) {
this.MyLabel1.Text = this.str1; // <-- this.str1 has the correct value loaded in the list view itemdatabound event handler.
this.MyLabel2.Text = this.str2; // <-- this.str2 has the correct value loaded in the list view itemdatabound event handler.
}
3) The ListView PreRender method is called.
4) The page shows and everyting is ok!
Page posts back after selecting a node in the TreeView
1) Load page method is executed but it does nothing.
2) MyLVPaging_TreeView_SelectedNodeChanged is executed. Here I can see that everything has the correct value:
protected void MyLVPaging_TreeView_SelectedNodeChanged(object sender, EventArgs e) {
this.ViewState["PageIndex"] =
int.Parse(this.MyLVPaging_TreeView.SelectedNode.Value); // <-- The new page
((DAO)this.ViewState["DAO"]).PageIndex =
(int)this.ViewState["PageIndex"]; // <-- Index saved
// After setting the new index, GetData will return another set of results
this.MyLV_ListView.DataSource =
((DAO)this.ViewState["DAO"]).GetData(); // <-- DataSource is changed
}
3) ListView's ItemDataBound event handler is executed. Well, here, debugging I can see the same as before, I mean, I can see that new values, new Data have been bound to the ListView, in fact I can inspect new values that are assigned to the template item.
Obviously, as before, after the method is executed, the debugger cursor moves to MyWebControl.ascx.cs to the control's Page_Load method.
HERE IS EVIL: I can see the following:
protected void Page_Load(object sender, EventArgs e) {
// Note: inspecting this.IsPostBack I get true!
this.MyLabel1.Text = this.str1; // <-- this.str1 is null and also this.MyLabel1.Text is null.
this.MyLabel2.Text = this.str2; // <-- this.str2 is null and also this.MyLabel1.Text is null. view itemdatabound event handler.
}
Well!!! IT LOSES STATE AND ALSO VALUES
PASSED BY THE LIST VIEW
HANDLER!!!!!!!!!
My question
What the hell is going on???
Notes
1) Please, do not focus too much on how I managed data binding on Load and PreRender events... I have a feeling this is not the error! I guess it is something related to the page lifecycle. However, if you think that this is important detail, let me know.
2) DAO and its function GetData() are a way to let you understand as quick as possible the scenario which is a little bit more articulated, but with the same exact structure I've shown here.
Thank you for your help.
From my comments:
Why don't you move the
this.MyLV_ListView.DataBind() from
PreRender to SelectedNodeChanged? And
why do you need the fields str1 and
str2 in your UserControl? The property
Str1 should get/set this.MyLabel1.Text
and the property Str2should get/set
this.MyLabel2.Text, because the
lables' Text are already stored in
ViewState.
Andry:
... so these kind of settings are not
to be made in the Load?
Me:
you don't need to wait for any event
to happen to set the label's text. The
properties should directly lead to the
corresponding Labels, hence your
fields str1 and str2 are redundant.
They will be disposed at the end of
the Page-Lifecycle as opposed to the
Text property of the Labels which are
stored in ViewState automatically
across postbacks.

Dropdownlist in masterpage value not updated after new selected

I would like some help with the following problem. I have a dropdownlist implemented in my masterpage. It has an sql data source from which it loads the values of companies. Depending on which value(company) selected, it shows that value in a label on a different page.
The ddl which is in the masterpage is ofc still visible and should display the selected value which it does at the 1st time a value is selected. But when i select another value in the ddl it shows the value which was 1st selected and so on. So it doesn't update or something.
My code:
This is the onselectedIndexChanged event handler:
protected void DropDownListType_SelectedIndexChanged(object sender, EventArgs e)
{
String input1 = DropDownListType.Text;
String input2 = DropDownListType.SelectedValue;
String url = "~/test.aspx?pcompany="+input1;
DropDownListType.SelectedValue = input2;
Session["Company"] = input2;
Response.Redirect(url);
}
and this is the code i'm using in my Page_load method from the masterpage:
if (Session["Company"] != null)
{
DropDownListType.SelectedValue = (String)Session["Company"];
}
If I remove this last piece of code from my page_load method it updates the label with value on the redirected page but it resets my ddl to default value instead of keeping it at 4 when value 4 selected.
I hope this is a bit clear to you all. Any help is appreciated. Ty in advance.
try setting the label value in the PreRender() method. The problem you're having is with the page life cycle. I would change your OnLoad method to use
if(!IsPostBack) {
if (Session["Company"] != null)
{
DropDownListType.SelectedValue = (String)Session["Company"];
}
}
This way you're only setting it once when the page loads and from then on the page will set the selected value automatically using viewstate.
The Load event is fired before the SelectedIndexChanged event, that's why you don't have it set in Session yet.
See ASP.NET Page Life Cycle
just set the AutoPostback property of the DropDownList to true and then it will work.
This is because otherwise the onselectedIndexChanged will be called only on PostBack from a button or any other field.
And also, as the above answer says, use this code:
if(!IsPostBack) {
if (Session["Company"] != null)
{
DropDownListType.SelectedValue = (String)Session["Company"];
}
}

Categories