Why would formview disappear in Edit Mode - asp.net

I know I must be missing something simple but I cannot find it so I will pose the question here. I have a formview with two templates (item and edititem).
The form is bound to the itemtemplate in the page_Load event and works fine. However, if is use !IsPostBack in the code-behind, the formview disappears when the edit button is clicked. If I remove the postback check from page_load, then the form view appears after the edit button is clicked.
The page does have viewstate enabled.
In general, what steps are needed to get the formview to transition between modes correctly?
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
source = Session["Source"].ToString();
acctType = Session["AccountType"].ToString();
acctNumber = Convert.ToInt32(Session["AccountNumber"]);
if (source == "LifeLineDS")
{
ObjectDataSource fvObjDS = new ObjectDataSource();
fvObjDS.TypeName = "LifelineDataAccess.LifelineSubscriber";
fvObjDS.SelectMethod = "GetLifelineDSSubscriber";
fvObjDS.SelectParameters.Add(new Parameter("AcctType", TypeCode.String, acctType));
fvObjDS.SelectParameters.Add(new Parameter("AcctNumber", TypeCode.String, Session["AccountNumber"].ToString()));
fvObjDS.DataBind();
if (fvObjDS != null)
{
fvSubscriber.DataSource = fvObjDS; //subscriber.ToString();
fvSubscriber.DataBind();
initialProgramValue = (fvSubscriber.FindControl("txtEligibility") as TextBox).Text;
}
}
// more code for other sources...
}
protected void btnEdit_Click(object sender, EventArgs e)
{
fvSubscriber.ChangeMode(FormViewMode.Edit);
fvSubscriber.DataSource = Session["subscriber"]; //Adding this line resolved !IsPostBack problem
fvSubscriber.DataBind();
ObjectDataSource programsObjDS = new ObjectDataSource();
programsObjDS.TypeName = "LifelineDataAccess.LifelineSubscriber";
programsObjDS.SelectMethod = "GetPrograms";
DropDownList ddlEligibility = ((DropDownList)(fvSubscriber.FindControl("ddlEligibility")));
if (ddlEligibility != null)
{
ddlEligibility.DataSource = programsObjDS;
ddlEligibility.DataTextField = "ProgramName";
ddlEligibility.DataValueField = "ProgramName";
ddlEligibility.SelectedValue = initialProgramValue; // Set selected value to subscribers current program
ddlEligibility.DataBind();
}
}

This
fvSubscriber.ChangeMode(FormViewMode.Edit);
fvSubscriber.DataBind();
seems to not to set the data source. The rule is that either you have the DataSourceID set in the declarative part of your code (*.aspx, *.ascx) and the binding is done automatically upon each postback OR you bind programmatically which involves setting the data source and calling the DataBind().
My recommendation would be to move your ObjectDataSource to the declarative part of the code and set the DataSourceID on the FormView to the ID of the ObjectDataSource. This is clean and easy and the binding works always.

Related

ReportViewer.Find not working

I have a textbox, and a link button. On the same page I have a reportviewer.
The reportviewer is in updatepanel with linkbutton as async postback trigger.
I'm trying to find string (entered in textbox) in the report; when linkbutton is hit.
protected void lbtnFind_Click(object sender, EventArgs e)
{
ReportViewer1.Find(txtSearch.Text.Trim(), 1);
}
But that line gives error: Some parameters or credentials have not been specified Please help.
If txtSearch is a control you added, it will not be inside ReportViewer1.
If txtSearch is a control inside your ContentTemplate you should be searching in that control as follows:
var txtSrch = (TextBox)myUpdatePanel.ContentTemplate.Controls.FindControl("txtSearch");
You can get the text value from there and then set the parameters for the ReportViewer1 and refresh it.
ReportParameter[] parameters = new ReportParameter[1];
parameters[0] = new ReportParameter("Search", txtSrch.Text);
ReportViewer1.LocalReport.SetParameters(parameters);
ReportViewer1.RefreshReport();

Sorting a gridview using a datatable, and datasource that is an ArrayList

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.sorting.aspx
This article deals with creating a datatable first, then creating a gridview from it, to aid in sorting. My predicament is slightly different.
I have a Gridview, that on Page_Load, I set the datasource to an ArrayList, and bind.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.GridView1.DataSource = RequestManager.Instance.GetAllRequests();
this.GridView1.DataBind();
}
}
Now I would like to sort this GridView, so on the aspx page, I set AllowSorting="true", and OnSorting="GridView1_Sorting". So far, so good. I have the SortExpressions set in the BoundFields, and when I click on it, I know the _Sorting event is triggered.
Now, since this is a postback operation, I cannot simply cast the datasource of the gridview to a DataTable to sort. Saving to ViewState is an option, but I cannot figure out how to do it.
I would like to use the simple solution on this page, except for the DataTable not being available to me. Thanks for looking.
If you're able to target .NET v3.5, I recommend using Linq. In your _Sorting event handler, get the array list you did in the Page_Load and rebind it.
For example, if the type contained in the array list are MyType instances that have properties named Default and SomeField:
protected void Grid_Sorting(object sender, GridViewSortEventArgs e)
{
Func<MyType, object> keySelector;
if(e.SortExpresion == "SomeField")
{
keySelector = dataItem => dataItem.SomeField;
}
else
{
keySelector = dataItem => dataItem.Default;
}
ArrayList dataItems = RequestManager.Instance.GetAllRequests();
this.GridView1.DataSource = dataItems.OfType<MyType>().OrderBy(keySelector);
this.GridView1.DataBind();
}
That will get you started, then later inspect the sort expression to see if it ends with ASC or DESC and conditionally call .OrderByDescending(keySelector).
Finally, I don't recommend stashing the list in ViewState, as the ObjectStateFormatter is only optimized for a handful of types. http://msdn.microsoft.com/en-us/library/system.web.ui.objectstateformatter.aspx
Maybe consider ASP.NET cache instead.

Refreshing report inside dynamically created TabPanel

I am having a ReportViewer inside the inner TabContainer TabPanel which i generated dynamically in Page Init event.
I load the report on OnActiveTabChanged event and I want to refresh the report on SelectedIndexChanged event.
How ever report doesn't change when I change the selected value of the DropDownList.
Note: I debug and the loadReport inside the SelectedIndexChanged execute properly.
Following is part of my code.
protected void DDL_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList DDL = (DropDownList)sender;
ReportViewer rptViewer = (ReportViewer)DDL.Parent.FindControl("rptDateElectricity");
if (rptViewer == null)
{
rptViewer = new ReportViewer();
rptViewer.ID = "rpt" + "Date" + "Electricity"
rptViewer.Width = Unit.Pixel(1100);
loadReport(rptViewer, DDL, "Electricity", "Date");
DDL.Parent.Controls.Add(rptViewer);
}
}
protected void TCInner_OnActiveTabChanged(object sender, EventArgs e)
{
..............................
..............................
ReportViewer rptViewer = (ReportViewer)DDL.Parent.FindControl("rptDateElectricity");
if (rptViewer == null)
{
rptViewer = new ReportViewer();
rptViewer.ID = "rpt" + "Date" + "Electricity"
rptViewer.Width = Unit.Pixel(1100);
loadReport(rptViewer, DDL, "Electricity", "Date");
loadReport(rptViewer, DDL, monitoringObject, timePeriod);
}
}
}
I believe that this is a problem with view state.
I tried to set the EnableViewState false for the report viewer.
When i did i got the following runtime error:
"Microsoft JScript runtime error:
Sys.WebForms.PageRequestManagerServerErrorException: The Update
method can only be called on UpdatePanel with ID 'ReportArea' before
Render." Can anybody give a solution to this.
Thanks in advanced.
I got the same error when I told my report to autoRefresh, and it was caused by some javascript I'd inserted to override some of the ReportViewer's javascript (Microsoft.Reporting.WebFormsClient._ReportAreaAsyncLoad) to fix an error I'd been getting earlier. My custom javascript was triggering extra async load postbacks. I guess autorefresh conflicts with that.
Not sure if that's the cause of your problem though.

Dynamically update dropdownlist

I have this dropdownlist populated and everything. The only problem is that whenever I add a new item in the database through my website, the dropdownlist doesn't update for some reason.
private CurrentUser _cu = new CurrentUser();//just to check if use is an admin or not.
protected void Page_Load(object sender, EventArgs e)
{
_cu = (CurrentUser)Session[Common.SessVariables.CurUser];
if (!_cu.CanReport) { Response.Redirect("~/default.aspx"); }
CurrentUser cu = (CurrentUser)Session[Common.SessVariables.CurUser];
if (!IsPostBack)
{
foreach (PrefixAdd loc in cu.Prefix)//Prefix is a Property
{
ListItem x = new ListItem(loc.Prefix);
PrefixID.Items.Add(x);
}
}
}
#Wayne I'm using a store procedure to just insert a Prefix like Pre,yes,sey, etc. Then the list is populated with prefixes.
StringBuilder sbSQL = new StringBuilder(255);
sbSQL.Append(string.Format("exec insPrefix #Prefix=N'{0}';", PrefixBox.Text.Trim()));
string msg = string.Empty;
msg = (_oDAW.ExecuteNonQuery(sbSQL.ToString())) ? string.Format(Common.GetAppSetting(Common.ConfigKeys.User_Submit_Success),
PrefixBox.Text.Trim()) : Common.GetAppSetting(Common.ConfigKeys.SubmitFail); //this is a somewhat custom method for CS and databinding.
# Yuriy Rozhovetskiy Yea I add new items to this page with the dropdownlist.
Whenever you add an item to your database, you have to rebind your drop down list.
yourDropDown.DataSource = //...
yourDropDown.DataBind();
That is, DropDownLists (and other controls) have no way of knowing that their data has changed behind the scenes, they can't automatically detect it. You have to tell the controls to rebind their data manually.
Good job on the Page_Load(...){ if !(IsPostback) part.
Since you add new prefix on this page with some postback item you need to add this new item to PrefixID dropdown's Items collection and update the CurrentUser instance in Session right after you have add new prefix to database.

ASP.net list of dropdownlists - similar to Access continuous form

What I'm looking for is a way to mimic the MS-Access style continuous form within asp.net. In one particular case, I want a control, bound to a datasource which returns a dropdownlist for each row, bound to the value within the datasource. Any change to any of the dropdownlists' would perform an update to the database instantly.
I have got halfway to achieving this using a repeater control, with the DropDownList.SelectedValue assigned within the Repeater.ItemDataBound event.
But now, supposing I add an OnSelectedIndexChanged event to the DropDownList - how would I then query the repeater to know which row I was on (to get the primary key value, for example)
I'm not sure this can be done easily.. so the question is what should I really be doing? I don't want to use a GridView that requires me to select a row to edit.. I just want to have the dropdownlists autopostback for any updates.
Hope that's clear?!
Cheers! :D
For examples sake, lets say we are binding to a custom class called Record
public class Record
{
public int Id;
public string Value;
}
If you put custom logic on the Repeater.OnItemCreated event you can attach the primary key to the id of the drop down list
protected void Repeater_ItemCreated(object sender, RepeaterItemEventArgs e)
{
if (!(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem))
return;
var dataItem = e.Item.DataItem as Record;
if (dataItem == null) return;
var dropdown = e.Item.FindControl("myDropDown") as DropDownList;
if (dropdown == null) return;
dropdown.ID = dropdown.ID + dataItem.Id;
}
Then on the SelectedIndexChange, you can pull the id off of the dropdown that fired the event.
protected void SelectedIndexChanged(object sender, EventArgs e)
{
var dropdown = sender as DropDownList;
if (dropdown == null) return;
var stringId = dropdown.ID.Replace("myDropDown", "");
int id;
if (Int32.TryParse(stringId, out id))
{
updateRecord(id, dropdown.SelectedValue);
}
}
It's very much an ugly hack, but it should allow you to do what you want.
Easiest way to tackle this would be to mimic the Access continuous form ASP.NET style. Which would be to make a UserControl to handle the row-level UI, then put said UserControl in a repeater.

Resources