I have struggled to find a clear and concise answer to this simple question.
Given an object property in the page named "SomeObj", is it possible for two way data binding like this:
<asp:TextBox ID="TextBox1" runat="server" Text="<%# SomeObj.SomeProperty %>" />
This will correctly display SomeProperty in the textbox if we call "this.DataBind()" in Page_Load. However, my object property is never written to during postback - have I done something wrong or is this actually not possible?
Should I put this control inside some container like FormView or DetailsView? At what point in the page life cycle should I be able to see my object property being written to?
All the thousands of copy-and-paste tutorials out there focus on lists and grids and binding to Sql Data Sources, which I do use successfully. But for a simple, single object surely there is a way that does not require extraneous containers, data sources and code-behind?
Of course the code to do this in code-behind for one text field is trivial, but no longer when multiplied by loads of properties and loads of pages. I have instead written two simple routines that use reflection to automatically load controls with property values and then save the control values back to the properties. With these routines we can then fill the page with simple markup like this:
<asp:TextBox ID="SomeObj_SomeProperty" runat="server" />
By simply naming the controls the same as the object property and calling my two methods at the appropriate times I get two-way data binding and the code-behind has very little code in it other than creating the main object, and I do not have to wrap the markup inside other controls just to get the data binding to work.
I am not very experienced with ASP.NET and it seems like I am doing something that should already be done for me.
UPDATE:
Note that if I try to use Bind() instead I get the usual data binding exception because there is no special data-binding control like a list or grid view:
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("SomeObj.SomeProperty") %>' />
Gives this error:
Databinding methods such as Eval(), XPath(), and Bind() can only be used
in the context of a databound control.
Related
Suppose I have a GridView whose data source is a list of type Meeting. Every Meeting object has a property of type Employee, and at the same time every Employee has a Name property.
If I want to show the name of the Employee in a GridView, I should do this:
<asp:TemplateField>
<ItemTemplate>
<asp:Label Text='<%# Eval("Employee.Name") %>' runat="server" />
</ItemTemplate>
</asp:TemplateField>
My question: Why I'm not able to do the same thing with Bind? When trying to display the property of a property using Bind, I get a compilation error. What are the differences in this case about using Eval or Bind?
English is not my first language, sorry for all possible mistakes.
If you just need to display data on the screen from DataSource it’s enough to use Eval
But if you need to edit data inside of Grid you have to use Bind method. Because it provides two way binding you can read data from DataSource and you can write data back
If you try to edit some row in Data Grid and want to make some changes in code behind class in OnUdpdating event, data with Eval method will not be available instead of Bind method.
The difference between these two is that Eval is used for read only purpose and Bind is used for read/edit purpose. For example Eval can be used to bind the Text property of an asp.net Label control whereas Bind can be used to bind the asp.net TextBox control so that it can be edited to meet some requirement.
For more info see Mr.Darin Dimitrov answer
I am using ASP.NET Web Forms and i created a custom .ascx user control which represents a Car having properties like Type, Picture and Color.
Now i try to add on user interface this custom control in a repetitive way. Lets say if i have in database 5 cars, then 5 user controls will be render on UI preferable inside an asp control.
I was looking for such a control, studying the grid view, and repeater but they seems to have as data source only lists of objects which are build from "primitive" types not objects like a list of my custom ascx control.
My question is if i can somehow to render those user controls inside a repetitive cycle inside an asp or html control which gives the option to format it (supports css) ? (and if so please provide me an example)
Create a ListView with your user control inside of it, and then bind a List<CarObject> to that ListView
<asp:ListView ID="listView1" runat="server">
<ItemTemplate>
<myUC:MyUserControl ID="myUserControl" runat="server" />
</ItemTemplate>
</asp:ListView>
Bind a list of your object, such as List<Car>, to that list view, listView1.DataSource = myListOfCars;. Then in a ItemDataBound event bind your object to your user control.
You could also, alternatively, place the markup from your user control inside of the ListView, and then bind the information inside of an ItemDataBound event and sidestep the whole user control issue altogether. This still allows you to reuse the markup.
I need to populate a text box using some queries. I an newbie in asp.net, whereas i was able to do that with asp:DropDown. How should i do that?
You need to use the Page.DataBind() to bind public properties with your page.
<asp:textbox id=txt text="<%# custID %>" runat=server />
Refer the databinding overview
ASP.NET introduces a new declarative syntax, <%# %>. This syntax is
the basis for using data binding in an .aspx page. All data binding
expressions must be contained within these characters.
No data is rendered to the control until you explicitly call either
the DataBind method of the Web server control or until you invoke the
page-level Page.DataBind method. Typically, Page.DataBind (or
DataBind) is called from the Page_Load event.
I am new to ASP .NET web controls, but not ASP .NET in general or C#.
I am wondering how I can limit the allowed content types to a specific class.
I have made a custom web control called TabPanel, and I want it to only be able to contain TabPages.
As an example, the following markup should be illegal, since it contains a checkbox.
<cc1:TabPanel ID="TabPanel1" runat="server">
<cc1:TabPage runat="server">
this is a simple test
</cc1:TabPage>
<cc1:TabPage runat="server">
this is another simple test
</cc1:TabPage>
<asp:CheckBox runat="server" />
</cc1:TabPanel>
In this case, I wouldn't want the checkbox to be there. How can I block this from happening?
I have not tried exactly what you are after but based on other things I have done I would try this:
Create a property in TabPannel that is a collection of TabPages (call it Tabs for demonstration purposes). This can be an array, a list, or a custom collection class, the key is to have typed to only accept TabPages as members.
Give the property the [PersistenceMode(PersistenceMode.InnerProperty)] atribute.
Override CreateChildControls to add the contents of the collection to the control.
If you do it this way then your mark up should end up looking something like this:
<cc1:TabPanel ID="TabPanel1" runat="server">
<Tabs>
<cc1:TabPage runat="server">this is a simple test</cc1:TabPage>
<cc1:TabPage runat="server">this is another simple test</cc1:TabPage>
</Tabs>
</cc1:TabPanel>
and it should not allow anything that is not a TabPage to be nested inside of the Tabs property.
http://msdn.microsoft.com/en-us/library/9txe1d4x(v=VS.90).aspx is a walk through demonstrating this technique in detail.
I figured it out.
Had to throw an exception under AddedControl procedure that I overrided from the WebControl if the type of the control being added was not of the type I wanted.
Now the designer shows a beautiful red error-message on the control itself, preventing me from doing such a foolish thing.
Awesome!
I'm going to take a guess here, but based on some quick googling I think you're looking for the ControlBuilder. The demo limits their control to an object called "mycell", but I don't see any reason why this couldn't be limited to your own objects, or build-in ASP.NET controls (i.e. Panels but not TextBoxes, etc.)
As a last resort, I'm sure you could hijack the rendering method and only render controls within the pre-determined class set, but this seems hack-ish at best.
I have an ASP.NET web app that places several string data into an object as properties. The string data is sourced from a JSON feed from Twitter. A collection of my TwitterMessages is held in a Generic List.
What I want to do is use an asp:repeater to iterate through my List<T> to display all of the contents of the objects it holds, by using <%# Eval("MyURL") %>. MyURL is the name of a property inside my TwitterMessage object.
In a previous question I was advised to use the asp:Repeater template to display my data in a custom HTML table. So being able to use a template somehow or other, is really what I'm interested in.
Where I am struggling is in working out how to perform a databind to the Repeater so I can reference my object data in the .aspx page.
I am aware that I need to use the ItemDataBound method in order to make a data-bound event so that I can reference the property names in my string data object.
Hope that's enough info for some much appreciated help! :)
It's pretty straightforward to databind to your repeater. Depending on where your list object resides, you can either bind your repeater using markup, or codebehind.
If you want to do it in markup, you should make an ObjectDataSource wrapper around the List. Something like this:
<asp:Repeater ID="rpt" runat="server" DataSourceID="twitterFeedSource" >
<ItemTemplate>
<tr><td><%# Eval("MyURL") %></td></tr>
</ItemTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="twitterFeedSource" runat="server"
SelectMethod="GetTheListOfTwitterFeedObjects"
TypeName="myTwitterFeedClass"
>
</asp:ObjectDataSource>
The GetTheListOfTwitterFeedObjects method should return the list of objects. Each object would need to have the property MyURL. You can of course extend your template and bind to any other properties that your twitter objects have.
Otherwise, you can do it straight from the code. Simply do something like this in Page_Load:
if (!IsPostBack)
{
myRepeater.DataSource = myGenericList;
myRepeater.DataBind();
}