How do I reference the databound control from an ObjectDataSource event? - asp.net

Take for example a DetailsView control with an ObjectDataSource as its datasource.
Normally in the DetailsView.ItemUpdated event I would grab a reference to the details view by casting the sender:
DetailsView dv = (DetailsView)sender;
In certain situations it becomes necessary to handle the event inside the ObjectDataSource.ItemUpdated event. In this case sender is now of type ObjectDataSource. What I want to be able to do is write clean code that isnt hardcoded like
Label label1 = DetailsView1.FindControl("Label1");
I looked over the documentation and also did some searches but couldnt find how I would write some code like the following:
protected void ObjectDataSource1_Inserted(object sender, ObjectDataSourceStatusEventArgs e)
{
ObjectDataSource ods = (ObjectDataSource)sender;
DetailsView dv = (DetailsView)ods.SOMETHING_HERE;
}
Does anyone know what I should be putting in the SOMETHING_HERE in the snippet above?

That's happen because the "OnInserted" event is suppose to be an event examine the values of a return value or output parameters, or to determine whether an exception was thrown after an Insert operation has completed. The return value, output parameters, and exception handling properties are available from the ObjectDataSourceStatusEventArgs object that is associated with the event.
What you can do here is just call ObjectDataSource.select() that returns the view in this case but I don't think it's a good choice.
You should review you business logic and try to manage it somewhere it makes more sense
Anyway your code should look like the below:
ObjectDataSource ods = YourDataSource.select();
DetailsView dv = (DetailsView)ods;

Considering the example you provided, I don't think there is anything you can replace for Something_Here. It is the ODS linked to DV and not the other way. Also one DataSource can be linked to several DataBound Controls.
So as far as I know it is simply not possible.

Related

How to access the bound DataSource item in the ASP.NET ListView's DataBound event?

I know the question has already been posted here but we didn't get to an real solution.
I have bound my ListView to an SqlDataSource and I want to write some text in a control present in the view created in the LayoutTemplate depending on some properties of the rows returned.
Obviously, I'm using the ItemDataBound event to feed my items but this is not the point.
The spontaneous solution was to bind the ListView.DataBound event and access the raw datasource (a DataTable?) and do the required calculations.
I inspected the Items property and, despite it was not empty, the related DataItem property was null.
Do you have any suggestion?
The only work-around I can come to is to execute the calculations in the ItemDataBound event and accumulate the result in some private fields. But it's really ugly to see and makes harder to get some of the required values.
Thanks a lot.
In the ItemDataBound you should be able to access the data source for the Listview through the DataSource property (you might need to cast it to a DataTable):
protected void Listview1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
DataTable sourceData;
sourceData = (DataTable)Listview1.DataSource;
// sourceData is a DataTable, you can run .Compute or whatever you need
}

ASP.NET 2.0: Specifying an instance of an object for an ObjectDataSource

I'm using an ObjectDataSource to bind data to a GridView; it works fine except that it always creates a new object to use as a data source. I can do all the setup just fine but I cannot use an instance of an existing object to specify as the "data source" for it. Is it possible to do this? If so, how?
If it's not possible, why?
EDIT: Here's the gist of what's going on (object types changed): On the first page you are editting the attributes for a dog. One of the attributes is "has puppies" and if it's true, the next page you specify the names of those puppies. What's happening in my case is that those puppies are not getting linked to the original dog but to a "new" dog. (The implication that my problem is a "female dog" was coincidental. ;-) )
Create an event handler for the ObjectCreating event on the ObjectDataSource.
You can assign the instance to using the ObjectDataSourceEventArgs property
protected void ObjectDataSource1_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
e.ObjectInstance = myObject;
}
Wire this event up in the markup too
<asp:ObjectDataSource OnObjectCreating="ObjectDataSource1_ObjectCreating" />
As I just discovered in my own question here, items stored in the Application Cache are going to pass themselves as a reference for use. You may consider storing your data there (or potentially in the Session as well) and pass items that way.

FormView_ItemUpdating in not updating

I am using a FormView to update an existing SQL Server record. The rows from the sqldatasource display fine in the FormView and I can edit them. When I click Update, I get the ItemUpdating event but not the ItemUpdated event and the revisions are not written to the database.
Can anyone help me in this please.
In your ItemUpdating event handler, make sure of the following things:
-If you are not using optimistic concurrency checking, remove any old values the FormView may be placing in the OldValues collection.
-Make sure that all of the parameters required by your stored procedure, query, or data source have values and are named correctly in either the Keys or NewValues collections (and make sure that no duplicates exist).
In some cases (usually when an ObjectDataSource is involved), I've had to override the values set by the FormView control, by doing something like this:
protected void myFormView_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
// remove the old values
e.Keys.Clear();
e.OldValues.Clear();
e.NewValues.Clear();
// set the parameter for the key
e.Keys.Add("#key", valueGoesHere);
// set other parameters
e.NewValues.Add("#param1", aValue);
e.NewValues.Add("#param2", anotherValue);
}
It's not pretty, but it give you absolute control over what gets passed to the DataSource. Generally you should not have to do this if the controls in your FormView are all bound using Bind() for two-way databinding (instead of Eval), but at the very least you could put a break point in ItemUpdating and open up the e.Keys, e.OldValues, and e.NewValues collections to see if the contents are what you expected.
A next step would be to launch SQL Server Profiler to run a trace and examine the actual query being performed.
If you take out the ItemUpdating event and the ItemUpdated event, does your SQL statement execute without errors?
If so, why don't you post some of the code you are using?
Can we see what the sqldatasource looks like? Did you remember to put all the parameters in the sqldatasource under the insert and update parameters list?
Oh also are you setting the cancel property at all in the itemupdating event?

How do I set up ObjectDataSource select parameters at runtime

I'm trying to add parameters to an objectDataSource at runtime like this:
Parameter objCustomerParameter = new Parameter("CustomerID", DbType.String, customerID);
Parameter objGPDatabaseParameter = new Parameter("Database", DbType.String, gpDatabase);
//set up object data source parameters
objCustomer.SelectParameters["CustomerID"] = objCustomerParameter;
objCustomer.SelectParameters["Database"] = objGPDatabaseParameter;
At what point in the objectDataSource lifecycle should these parameters be added (what event)? Also, some values are coming from a master page property (which loads after the page_load of the page containing the objectDataSource).
Add them to the event for the operation you are trying to use. For example, if these parameters are part of the SELECT command then add them to the Selecting event, if they need to go with the UPDATE command then add them on the Updating event.
The ObjectDataSource raises an event before it performs each operation, that's when you can insert parameters (or validate/alter existing parameters).
Also, don't try and modify the parameters collection of the ODS itself. You want to add your parameters to the ObjectDataSourceSelectingEventArgs that is passed to the event handler.
Something like:
e.InputParameters["CustomerID"] = customerId;
e.InputParameters["database"] = dbName;
Add as early as possible; at the PreInit event. This is part of initialization so should be done there.
See the ASP.NET Page Life Cycle Overview for more information.

asp:DropDownList Error: 'DropDownList1' has a SelectedValue which is invalid because it does not exist in the list of items

I have a asp.net 2.0 web site with numerous asp:DropDownList controls.
The DropDownList control contains the standard info city, state, county etc... info.
In addition to the standard codes the site also has custom codes that the users can configure themselves.
For example a animal dropdown may contain the values Dog, Cat, Fish, ect...
I am popluating the DropDownList from a SQL 2005 table that I created e.g. tblCodes
Everything works great and users are able to add orders using the numerous DropDownList controls to choose items from the list.
The problem occurrs if a user wants to change one of their custom dropdowns. For example a user would like to change the verbage
on a animal type control from Dog to K9. This is where the problem starts.
For all new orders the drop down works fine. When the user retrieved an old order
I get the following error in the C# codebehind
"'DropDownList1' has a SelectedValue which is invalid because it does not exist in the list of items."
What's happening is the old order has a database field value of Dog and the DropDownList no longer has Dog in its list since the user changed it to K9.
Any ideas on a workaround?
Is there a way to make the asp:DropDownList accept items not seeded in its list?
Is there another control I could use?
I solved this exact same problem just two days ago. First, I moved the code that set the SelectedValue to a PreRender handler for the DropDownList. Then, I add logic to first check to see if the value is in the drop down list. If not, I add it.
Here's my code. ddSpecialty is my drop-down list, populated with "specialties" from the database. registration.Specialty is the specialty that the user chose, which may or may not be in the drop down, since that particular specialty may have been deleted since they last chose it.
protected void ddSpecialty_PreRender(object sender, EventArgs e)
{
if (!ddSpecialty.Items.Contains(new ListItem(registration.Specialty)))
ddSpecialty.Items.Add(registration.Specialty);
ddSpecialty.SelectedValue = registration.Specialty;
}
I've become very fond of the following little snippet for setting DropDownList values:
For non-DataBound (eg Items added manually):
ddl.SelectedIndex = ddl.Items.IndexOf(ddl.Items.FindByValue(value));
For DataBound:
ddl.DataBound += (o,e) => ddl.SelectedIndex = ddl.Items.IndexOf(ddl.Items.FindByValue(value));
I sure do wish though that ListControls in general didn't throw errors when you try to set values to somthing that isn't there. At least in Release mode anyways it would have been nice for this to just quietly die.
Your SelectedValue should be a unique id of some sort, that doesn't change. The Text value that gets displayed to the user is something seperate, and can change if necessary without affecting your application, because you associate the id with your Order, not the displayed string value.
I'm not sure it's the same issue, but I had a similar sounding issue with trying to bind a DropDownList that I wanted to contain in a GridView. When I looked around I found a lot of people asking similar questions, but no robust solutions. I did read conflicting reports about whether you could intercept databinding, etc events. I tried most of them but I couldn'f find a way of intercepting or pre-empting the error.
I ended up creating a subclass of the ddl, intercepting the error from there hacking a fix.
Not tidy but it worked for my needs. I put the code up on my blog in case it's of help. link text
Check this:
http://www.codeproject.com/Tips/179184/ASP-dropdownlist-missing-value-error.aspx
Ran into this myself. Oddly, ddl.ClearSelection(); didn't work. Had to use ddl.SelectedValue = null
Also noticed, that this must come AFTER I clear the items from the list ddl.Items.Clear(); which also seems weird. Setting the SelectedValue to null, then clearing the items still threw the error.
Once this is done, re-bind the list and re-select with new value.
Try this:
if (ddl.Items.Contains(new ListItem(selectedFacility)))
ddl.SelectedValue = selectedFacility;
I have made a workaround after having this problem very often. Unfortunate that MS still did not recovered this issue.
Anyway, my workaround is as follows.
1) I bind the data to the ToolTip property of the DropDownList
<asp:DropDownList ID="edtDepartureIDKey" runat="server" CssClass="textbox"
ToolTip='<%# Eval("DepartureIDKey") %>' DataSource="<%# DLL1DataSource() %>" DataTextField="DisplayField" DataValueField="IDKey"
onprerender="edtDepartureIDKey_PreRender">
2) On the prerender event i check the availibilty of the data, and if it is not in the list I simply add it, then set the selectedindex to the data valuei which I saved in ToolTip property
protected void edtDepartureIDKey_PreRender(object sender, EventArgs e)
{
DropDownList ddl = (sender as DropDownList);
if (ddl.Items.FindByValue(ddl.ToolTip) == null)
{
//I am pulling Departure Data through the ID which is saved in ToolTip, and insert it into the 1st row of the DropDownList
TODepartureData v = new TODepartureData(DBSERVER.ConnStrName);
TODeparture d = v.Select(Convert.ToInt32(ddl.ToolTip));
ddl.Items.Insert(0, new ListItem(d.DeptCode, ddl.ToolTip));
}
ddl.Items.FindByValue(ddl.ToolTip).Selected = true;
}

Resources