Connect UserControl to a Datasource (ObjectDataSource in my case) - c#

I'm trying to find a way to Databind a usercontrol to a datasource (an
ObjectDataSource in my case) like in the case below :
<uc1:AutoComplete ID="autoComCities" runat="server"
DataSourceID="objCitiesDS" DataValueField="Id" DataTextField="Name" />
I've try to find some good exemple with our lil' friend Google and I still
ain't find anything concret. Someone can show me or give me good links on
how I could do this. I mean, about how to handle it in my usercontrol ;o)
Thanks!
Edit
Note that in my case, it's not a Dropdownlist or any Bindable control in my usercontrol, its a normal asp.Net Textbox with some custom jQuery so when user type in the textbox, it shows "possibilities" under the textbox. So, I want to get values from the DataSrouce and put it into HTML so jQuery can Handles values and shows it to user.

You can't just use the ObjectDataSource, there is a lot of plumbing to get that to work. You can pass the ID and call the Select() method to perform the selection manually and then get the values from the data and render them out. You'll have to use reflection or DataBinder.GetPropertyValue method to extract the individual field values within each record.
HTH.

Related

binding long to user control property

I seem to have run across an issue with binding and I have looked everywhere to try to resolve it.
I have a user control in ASP.NET that has a Channel ID public property which is a long. I have added this user control to an empty ASPX page for testing. When I simply add a number for this property value (i.e. ChannelID="9") then it works perfectly. When I try to do the following:
ChannelID="<%#: ChannelID %>"
where ChannelID is a variable on the hosting ASPX page, it tells me it cannot convert from string to long as a compilation error.
What I have gathered so far through my research is that the data binding functions convert values to strings rather than retaining their original data types.
What I am trying to accomplish is to have multiple user controls in a single page that all bind a property through a shared interface to the same value of the host page. I know that I could do this in code behind but that is what I am trying to avoid. I also know that I could simply change the data type to string and then convert it before it is sent from the user control to the database....that will be the route I go if I cannot find another solution.
There is not really code I can post because the scenario is extremely basic.But here is the declaration of the user code on the host page:
<UC:ChanControl ID="ChanControl1" runat="server" IsActiveView="true"
DisplayMode="Normal" ChannelID="<%#: ChannelID%>" />
Again, the ChannelID property in the host page and the user control are both set to long.
Any suggestions would be greatly appreciated. Thanks.
try this ChannelID='<%#: Eval(ChannelID) %>'
or
ChannelID='<%#: Eval(ChannelID).ToString() %>'

Get HiddenField in JQuery inside Repeater

I have a Repeater control, and I need to access a HiddenField inside. I can't use:
<%= Control.ID.ClientID %>
And I can't use the class or cssclass attributes either?
So my question is rather simple, how can I access my HiddenField control inside my repeater?
My scenario is that I populate a multiselectable dropdown, and I need to know in an update function which elements I have selected, for this I use the HiddenField to store the Id's. Then in code behind I can access the HiddenField values and make a propor databind.
HiddenField control elements are rendered to inputs of type hidden, so, albeit not thoroughly understanding your vague scenario with limited application, you can access them in jQuery with a selector like so:
$("input[type=hidden]")
Depending on your situation you might want to constrain that selector yet more.
However, this is focusing on your inclusion of the jquery tag, though your example seems to want to use inline ASP.NET script to use managed code. Please clarify your intentions and ultimate goal.
You can use the class selector
Put a class over the hidden field.
And on change event of multiselectable find the appropriate hidden field and set it's value.
Edit-1
I will suggest you to put a class say ddl over the multiselectable dropdown.
Bind jquery on change method on this multiselect.
Using jquery parent and prev selectors you can set the values in the hidden field.
Exmaple
$(".ddl").change( function(){
$(this).parent().next().find("input:hidden").val($(".ddl").val());
});
This is just for and idea of my approach.
Edit 2
Here is a good example of how to use css-class over a hidden field.
Jquery Hidden Field
I found a solution which in fact is pretty easy :)
I used the ClientIDMode property on the HiddenField inside the repeater:
<asp:HiddenField ID="HiddenField_Pladser" runat="server" Value="Selected" ClientIDMode="Static" />
The ClientID value is set to the value of the ID property. Then it's easy in the JQuery script to access the value:
$("#HiddenField_Pladser").val();
And from the code behind I know the ItemIndex from the repeater, which makes it easy to create a data collection whit this code:
var data = from RepeaterItem item in rpPladser.Items
let hidden = ((HiddenField)item.FindControl("HiddenField_Pladser"))
select new
{
selected = hidden.Value
};
Please leve a comment if this implementation have flaws or somehow is bad.

Where to store web custom control data

I am creating a custom control extending WebControl. This web control allows the consumer to define a collection of columns in markup, something like this:
<Custom:CustomGrid>
<Columns>
<Custom:DataColumn HeaderText="FirstName" />
<Custom:DataColumn HeaderText="LastName" />
</Columns>
and put an IEnumerable in a DataSource property and this is rendered out to a table.
This control also allows paging. The IEnumerable in DataSource is the full list, and I display a page of the list at a time. I am already saving the current page, number of rows per page, etc. to viewstate. Should I also put the full list in viewstate? Maybe session?
This list can become a bit hefty. Maybe save in session with a random key, which is saved in viewstate?
What is the best practice here?
Edit: I don't think it's right to impose that all types in the IEnumerable be serializable. Is that fair? So do I need to copy the data source to some other data structure for serialization?
Edit 2: Even if I do use a base control instead of implementing RenderChildControls I will need to implement CreateChildControls, but I will still need to persist the data somewhere, or did I miss the point of the base class?
Indeed, not all IEnumerable instances will be serializable.
If the query is cheap to run I wouldn't persist the whole data set but just run the query again for a different page or a change in the sort order.
If you put the data in viewstate you'll end up with huge pages. Session state might be acceptable if you don't have many users, but large data sets with lots of users won't scale well. What if I bind a million rows to your control? Or what if your control was used in a repeater and shown 100 times on a page?
Are you sure you need to persist the data? This isn't premature optimisation is it?
Remember that your control is a UI component. The viewstate should hold enough information to maintain the UI state as it is. A change in state (e.g.: switching to a different page of results) is something for which your control should pass responsibility to the data source.
Take a look at good old GridView. It displays what you give it and remembers that. If you're using paging then it raises an event to say "the user has changed page; give me page x of data". For me, that's the best practice for a UI control.
For implementing databound control it is better to use base class which was designed to perform such task. For example in ASP.NET exist CompositeDataboundControl which can be used as a base class to implement custom data bound controls. I can advice to review the following Dino Esposito article:
http://msdn.microsoft.com/en-us/library/aa479016.aspx.
Basically if you create control like ASP.NET gridview then it is store values in viewstate. To be more clear it is create number of the DataRow controls which saved assigned values in viewstate. During postback it recreates the same number of rows and values are restored from viewstate. If you will save only datasource for example in session without using viewstate then you will need to redatabind data to your grid during every postback. So, if you create Server control similar to gridview then approach described in the Dino Esposito post will be very helpful because it shows how to create control similar to ASP.NET Server GridView control.

How do I show EmptyDataText only after the user submits the form?

I just created a basic ASP.NET website using Microsoft's walkthrough here. It has one page with a form that takes in some text input, runs a database query based on that, and results the results in a GridView. I added the EmptyDataText property to my GridView to explicitly show users when their search returns no results.
It all works as expected with one exception:
IIS shows my EmptyDataText of "No results found." even before the search form is submitted.
This defeats my purpose behind using EmptyDataText, which is to indicate to the user that the webpage successfully submitted their search but found no results, as opposed to took their search and threw it into the ether.
For example, a user who searches for something that cannot be found will see "No results found." both before and after their search, as opposed to nothing before and "No results found." after. The former behavior gives the impression that the search didn't work.
How can I configure my GridView to show the EmptyDataText only after the search form is submitted?
you are using sqldatasource that will bind automatically while loading the page. Bind the gridview programatically while clicking the search button
Don't bind your GridView until after the user has initiated a search. When you bind your GridView with a datasource that has 0 records, then the EmptyDataText will be displayed.
Chances are that you are binding it on Page_Load.
EDIT
Wherever a DataBind() is performed in your code (other than the action handler), remove it. Your DataBind() should only occur in the handler that receives the user action.
If Visual Studio is doing some voodoo behind the scenes with automatic binding, you can always default the grid to invisible. Make it visible when the user initiates a search.
Just don't databind it before the search, it will effectively be completely invisible until then.
UPDATE: maybe you are using a DataSourceID (which databinds automatically)?
UPDATE 2: First off, for what ever reason was the downvote (at least have a decency to leave a comment)? If it weren't for me the OP would still not have known where the problem lies - and secondly, just remove the DataSourceID property from the declaration, and set it back from codebehind when the user makes a search (you might want to call the GridView DataBind() method manually after that, but only if it doesn't do that on its own - try it without first).
As the other answers suggested, the GridView is being bound before the user makes a search because it has a DataSourceID attribute. As explained on MSDN, this attribute causes the GridView to automatically bind to the specified source:
To bind to a data source control, set the DataSourceID property of the GridView control to the ID value of the data source control. The GridView control automatically binds to the specified data source control and can take advantage of the data source control's capabilities to perform sorting, updating, deleting, and paging. This is the preferred method to bind to data.
To get the behavior I was looking for, I removed that attribute from the GridView and instead added an OnClick attribute to the submit button for my search form. The OnClick attribute refers to a method BindGridView that gets called only when the user submits the form.
All this method does is populate the DataSourceID with the same value it had before as an attribute:
public void BindGridView(object sender, EventArgs e)
{
GridView1.DataSourceID = "DataSourceID1";
}

Retrieving keys and NewValues within a Formview with manual data binding

I have a Formview binded in the code file to a generic list. Now, upon editing of a record, I wish to access the Keys and NewValues out of the FormViewUpdateEventArgs parameter of the ItemUpdating event handler method.
From what I've tried and searched over the internet as of now, I've come to know that updated values are only available if the Formview is set a data source control on the markup page else they'd be null. Is this true?
Secondly, at this moment I am casting the sender object to formview and individually filling each object property by using FindControl method to find and retrieve values present in the controls. Is this the best way to do this task?
As an example, this is what I am doing atm:
FormView currentForm = (FormView)sender;
ListObject.ID = new Guid(((HiddenField)(currentForm.FindControl("hdnID"))).Value);
ListObject.Name = ((TextBox)(currentForm.FindControl("txtName"))).Text;
Thanks for the help fellas!
Based on what your doing I would suggest you not use a FormView. FormView's are brilliant when working with datasources, but fail, when dealing with manual bound data the way you are, your basically overriding and manually building the form, and it would be simpler to just create a HTML form and ASP.Net Server Side Controls.
FindControl is an expensive operation and can become unwieldily. Simple assigning a value during the loop of your data to a server side control will be faster.
Alternatively as suggested, use a ObjectDataSource and bind your data to the FormView in that way.

Categories