How does Eval resolve to DataBinder.Eval? - c#

I'm trying to understand how the Eval() statement in ASPX/ASCX resolves to the DataBinder.Eval(context, expression) method, and more so where Eval("Value") goes to do it's Reflection before reaching this method?
I'm considering a couple of things that I'd like to do:
Introduce a similar thing to Eval - say EvalList() which justs dumps all the avaliable fields via Reflection that can be bound to, just to help when debugging/developing to determine what's avaliable on the context. I'd like to be able to just type EvalList() rather than SomeHelper.EvalList()
Re-direct Eval("") to a different method, which will Debug.Assert() or similar to warn the developer if it's being over-used and that something else might be better for performance.

Avoid Eval() all together and use the model binding feature in ASP.NET WebForms 4.5 and later, like this:
Pre-ASP.NET 4.5 way using Eval():
<asp:ListView ID="OrdersListView" runat="server">
<ItemTemplate>
<tr>
<td>
<asp:Button ID="EditButton" runat="server" Text="Edit"
CommandName="Edit" />
</td>
<td>
<asp:Label ID="OrderID" runat="server"
Text='<%# Eval("SalesOrderID") %>' />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
Model binding way:
<asp:ListView ID="OrdersListView" runat="server"
ItemType="YourNamespace.YourClass">
<ItemTemplate>
<tr>
<td>
<asp:Button ID="EditButton" runat="server" Text="Edit"
CommandName="Edit" />
</td>
<td>
<asp:Label ID="OrderID" runat="server"
Text='<%#: Item.YourPropertyName %>' />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
Note: Because ItemType is strongly typed you will get IntelliSense help in Visual Studio as you type Item..
Read ASP.NET 4.5 Web Forms Features - Strongly-Typed Data Controls for a quick overview of how you may never need Eval() again.

Related

Intermittent issue with Telerik TabStrip controls 'error creating control'

I've been getting an intermittent issue when i'm adding or using the telerik controls for tabstrip.
Here's what it looks like:
http://imgur.com/DYhXzNy
error creating control - telerik:RadTabStrip Duplicate component name 'RadTabStrip1'. Component names must be unique and case-insensitive.
What i've done:
Restarted VS
Uninstalled and reinstalled AJAX controls
Copied the Telerik.Web.UI bin file to my project's bin directory
All assemblies in web.config matches the current version of BIN i'm working on.
However, i'm still getting this issue more frequent than usual. It works again after clicking on the smart tag a couple of times or after restarting VS. recently, i had to keep on updating the BIN files and restart VS again to make it work. Also tried to clear VS cache but it keeps on happening. You guys have other suggestion on how i can permanently resolve this issue?
Update:
It happened again and seems to happen when try to follow the hierarchy w templates demo and do the following
Created a grid and included a nestedviewtemplate tag
made a radtabstrip inside the tag
placed one tab and added a multi page (used the smart tags at this point)
added a radlistview control. even added the placeholder tag.
Here's what i made after the tag
<telerik:RadMultiPage ID="RadMultiPage1" runat="server">
<telerik:RadPageView ID="RadPageView1" runat="server">
<telerik:RadListView ID="RadListView1" runat="server" ItemPlaceholderID="PlaceHolder1" DataKeyNames="JobOrderIndex" DataSourceID="SqlDataSource20">
<LayoutTemplate>
<div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</div>
</LayoutTemplate>
<ItemTemplate>
<table>
<tr>
<td><i>Job Order No.</i>
</td>
<td>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("JobOrderNumber", "{0}") %>'></asp:Label>
</td>
<th>Status</th>
<th>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("JobOrderStatus", "{0}") %>'></asp:Label>
</th>
</tr>
<tr>
<td>Plate Number</td>
<td>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("ProfitCenter", "{0}") %>'></asp:Label>
</td>
<td>Job Type</td>
<td>
<asp:Label ID="Label5" runat="server" Text='<%# Eval("JobType", "{0}") %>'></asp:Label>
</td>
</tr>
<tr>
<td>Job Order Date</td>
<td>
<asp:Label ID="Label4" runat="server" Text='<%# Eval("JobOrderDate", "{0:d}") %>'></asp:Label>
</td>
<td>Created By</td>
<td>
<asp:Label ID="Label6" runat="server" Text="Label"></asp:Label>
</td>
</tr>
<tr>
<td>Problem Description</td>
<td colspan="3">
<asp:Label ID="Label7" runat="server" Text='<%# Eval("ProblemDescription", "{0}") %>'></asp:Label>
</td>
</tr>
</table>
</ItemTemplate>
</telerik:RadListView>
So, i noticed that the error occurs as soon as i place the source for the RadListView control and certain other controls or smart tags for the grid or the tab will not show up.
If you notice that i'm not doing anything right (which is most of the time) please let me know and i would appreciate the wisdom you can share with me so it can be the Telerik master race i ought to be.
Thanks again,
C
I figured it out, I eventually added a control .aspx page and this error occurs when 2 controls with the same ID is found in one module.

Displaying "Empty" record templates in ASP.NET Listview

I'm currently coding a web application using ASP.NET. So far my use of ASP.NET and the application has been going great, however there is one feature I would love to have, but I cannot for the life of me figure out how to do it.
I want to use some sort of list/form view, which will show both data records and empty blank templates. For example, I want to use this as an "event booking" system, where the user would click an open slot and this would then be registered to our database. This open slot is the empty template I would like.
I've done a quick paint picture to illustrate what I mean:
I assume that I'm in the right direction using a ListView, but I would like some feedback/help on a better method to achieve this.
This is my listview code (it is somewhat basic, barebones almost):
<asp:ListView ID="LV_AvailableUpdateSlots" runat="server" ItemPlaceholderID="itemPlaceholder">
<LayoutTemplate>
<asp:PlaceHolder ID="itemPlaceHolder" runat="server"></asp:PlaceHolder>
</LayoutTemplate>
<EmptyDataTemplate>No data for this date.</EmptyDataTemplate>
<ItemTemplate>
<asp:Panel ID="Pnl_AvailableSlot" runat="server" CssClass="UpdateDiarySlotPanel">
<div class="FloatLeftInline">
<asp:Label ID="Lbl_ClientName" runat="server" Text="Name: "></asp:Label>
<asp:Label ID="Lbl_ClientNameEval" runat="server" Text='<%# Eval("RefID") %>'></asp:Label>
</div>
<asp:Label ID="Lbl_ClientProductEval" runat="server" Text='<%# Eval("ClientMainProductID") %>'></asp:Label>
<div class="FloatRightInline">
<asp:Label ID="Lbl_Version" runat="server" Text="Version: "></asp:Label>
<asp:Label ID="Lbl_VersionEval" runat="server" Text= '<%# Eval("Version") %>'></asp:Label>
</div>
</asp:Panel>
</ItemTemplate>
<InsertItemTemplate>
Insert here.
</InsertItemTemplate>
<EmptyItemTemplate>No data found.</EmptyItemTemplate>
</asp:ListView>
A ListView sounds good, but I does not hurt to take a look at Repeater
Repeater Web Server Control Declarative Syntax
If you have the time do a simple test implementing using a ListView and a Repeater to compare the benefits and see which one fits better your needs and appearance

Displaying search results in a Website

I am working on a website where i need to search for items from database and display it in page.I am using Datalist for displaying all the items .Now i need to display all the items according to some category.For example if i search for a two-wheeler it may have many categories or manufacturer's.Now I want to display it separately according to the categories.I can use many datalist to do that,but it will slow down the site.Instead which control can i use to do this.I searched the web but got no idea.So please give me sugessions to go about it.Any sugessions will be appreciated.
Code:
<asp:DataList ID="Dlitems" runat="server" RepeatDirection="Horizontal" RepeatColumns="4"
CellPadding="0" CellSpacing="15">
<ItemTemplate>
<table>
<tr>
<td>
<asp:ImageButton ID="ImgbtnProductImage" CssClass="imgdisp" ImageUrl='<%# Eval("ImagePath") %>'
CommandArgument='<%#Eval("ProductCode") %>' runat="server" CommandName="cmdView" />
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td width="20px"></td>
<td>
<img src="../Database/images/inr.jpg" alt="addtocart" />
<asp:Label ID="lblproductprice" runat="server" Text='<%# Eval("Price") %>' CssClass="lbl" />
</td>
<td>
<asp:ImageButton ID="imgbtnaddtocart" runat="server" Height="25px" Width="25px" ImageUrl="~/Database/images/addtocart.JPG"
ToolTip="Add to Cart" CommandArgument='<%#Eval("ProductCode")+","+ Eval("ProductName")+","+ Eval("ImagePath")+","+ Eval("Price")+","+ Eval("LongDescription") %>'
CommandName="addtocart" />
</td>
</tr>
</table>
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
You can take benefit of gridview.
Bind you gridview data.
And letter merge the rows.
For an example you can use the below link
http://www.codeproject.com/Articles/34337/How-to-merge-cells-with-equal-values-in-a-GridView
Edit 1
Some links
How to display group data separately using DataList in ASP.NET?
http://aspnettuts.wordpress.com/2010/10/21/asp-net-repeater-group-recordsdata-delete-selected-rows/
You should go for a Repeater control.
Example on Repeater
<asp:Repeater runat="server" ID="Repeater1">
<ItemTemplate>
<asp:ImageButton ID="ImgbtnProductImage" CssClass="imgdisp" ImageUrl='<%# Eval("ImagePathForTwoWheeler")%> + <%# Eval("ImagePathForCategory") %>'
CommandArgument='<%#Eval("ProductCode") %>' runat="server" CommandName="cmdView" />
</ItemTemplate>
</asp:Repeater>

disabling clientidmode

I have a Repeater like this
<asp:Repeater runat="server" DataSourceID="HeaderFooterSqlDataSource">
<HeaderTemplate>
<table border="0" width="100%">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<input runat="server" id="SelectRadio" type="radio"
name="HeaderFooter" onclick='SelectAndSetHeaderFooter(this);" %>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Now here when this Repeater is rendered the name attribute of my input radio "SelectRadio" gets auto generated but name attribute for all the radiobuttons in my repeater should be same so that they can work like a group & get checked / unchecked automatically according to other elements in that group, So how can I overcome this situation ??
Edit
I got the solution my self, Actually I have defined my input radio control as runat="server" because I thought otherwise Eval() binding wouldn't work but I was wrong Eval() binding does work without runat="server" , So when I remove that attribute name doesn't generated automatically and everything is fine now, But thanx to all for sparing time for my question.
Instead of hacking this you should use the built-in RaidoButtonList control.
<asp:RadioButtonList id="RadioButtonList1" runat="server">
<asp:ListItem>Item 1</asp:ListItem>
<asp:ListItem>Item 2</asp:ListItem>
<asp:ListItem>Item 3</asp:ListItem>
<asp:ListItem>Item 4</asp:ListItem>
<asp:ListItem>Item 5</asp:ListItem>
<asp:ListItem>Item 6</asp:ListItem>
</asp:RadioButtonList>
You want to look into the asp:RadioButton control (http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.radiobutton.aspx).
In particular the GroupName property on this control can be used to "specify a grouping of radio buttons to create a mutually exclusive set of controls"
So roughly speaking:
<asp:RadioButton runat="server" id="SelectRadio"
GroupName="HeaderFooter" %>' />
Edit: It seems that in this particular situation GroupName doesn't do what it is designed for. http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.radiobutton.groupname.aspx discusses it in the community content at the end but it boils down to the fact that it uses its current NamingContainer still as part of its name rather than just using the groupname you have given it. Thanks to the mysterious user1429080 for bringing that to my attention in comments.
The reason your radio buttons are not acting as a group is because you have runat="server" which will cause the name and id attributes to be prepended with parents' ids. The following will cause the radio buttons to behave as a cohesive group (note the lack of runat="server"):
ascx code:
<asp:Repeater ID="uxRadioSelections" runat="server">
<HeaderTemplate>
<table border="0" width="300px">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<input type="radio" value='<%# Eval("Name") %>' name="HeaderFooter" onclick="alert(this.value);"><%# Eval("Name") %></input>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
code behind:
protected void Page_Load(object sender, EventArgs e)
{
string[] names = new string[] {"Alvin", "Simon", "Theodore"};
uxRadioSelections.DataSource = names.Select(x => new { Name = x });
uxRadioSelections.DataBind();
}
However, the following will NOT perform as a cohesive group:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
Test
<asp:Repeater ID="uxRadioSelections" runat="server">
<HeaderTemplate>
<table border="0" width="300px">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:RadioButton Text='<%#Eval("Name") %>' runat="server" />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</asp:Content>
Due to the naming conventions you alluded to, these individual radio buttons will not find each other. ASP.NET uses RadioButtonLists to overcome this:
ascx code:
<asp:RadioButtonList ID="uxRadioButtons" runat="server">
</asp:RadioButtonList>
code behind:
protected void Page_Load(object sender, EventArgs e)
{
string[] names = new string[] {"Alvin", "Simon", "Theodore"};
uxRadioButtons.DataTextField = "Name";
uxRadioButtons.DataValueField = "Name";
uxRadioButtons.DataSource = names.Select(x => new { Name = x });
uxRadioButtons.DataBind();
}
This does not give you as granular control, but will provide easy server-side access to the selections. If all you need is javascript-related functionality and increased formatting flexibility, the first format may (which is nearly identical to what you provided) is your best bet. Good luck!
Another option is to set the ClientIDMode as 'static' which will set its value to that of the ID specified. Since it is a repeater control, all the items generated will thus have the same generated ID. So you simply set:
<asp:RadioButton runat="server" id="SelectRadio" GroupName="HeaderFooter" ClientIDMode="static">' />
This means that all generated controls will have the same ID specified i.e. "SelectRadio". This may or may not be problematic and you should be careful that this is exactly what you want.
Just a note, ClientIDMode is a feature of ASP.Net 4.0. More info here: ClientIDMode in ASP.NET 4.0 and here: MSDN. I hope this helps.
Update 1:
You can get more insights from this question asked before on StackOverflow. (It's jQuery though).

How to add/read items in ASP.NET

I have a set textboxes where the user enters something and I use them when they click Submit. I need to add a button that lets them add another identical set of textboxes on the fly, enter data into those and then when the submit button is pressed I need to grab the value from both sets. The amount of added sets of items can be unlimited.
What's the best way to handle something like this in ASP.NET/C#?
I've looked around and have basically only gotten that you can try to use JQuery on the front end which leaves the backend a mess or you can try to use a GridView and rebind it every time with new items which can get messy.
Any better/easier way to do this?
Thanks for the help.
Use a Repeater control for the first set of text boxes, and have it repeat for each extra listing.
Here's my comment control repeater. It's a little arcane, as it was the first control I ever made in asp.net, but it should get you going.
<asp:Repeater runat="server" ID="repeater"
onitemdatabound="repeater_ItemDataBound"
>
<HeaderTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
</HeaderTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
<ItemTemplate>
<tr id="trContents" runat="server"><td>
<table id="tableComment" runat="server"
width="100%" style="border-color:Black; border-width:1px; border-style:solid;background-color:#EEEE99">
<tr><td id="tdHeader" runat="server"
style="border-color:Black; border-width:1px; border-style:solid;padding: 5px">
<table width="100%" id="tableHeader" runat="server">
<tr>
<td>
<asp:Label ID="headerText" runat="server"
Text="<%# GetHeader((CommentRecord)Container.DataItem) %>" />
</td>
<td style="text-align:right"> <%-- OnClientClick="aspnetForm.target ='_blank';" --%>
<asp:Button ID="btnEdit" runat="server" Text="Edit"
PostBackUrl="<%$ AppSettings:TextEditor %>"
/>
<asp:Button ID="btnReply" runat="server" Text="Reply"
PostBackUrl="<%$ AppSettings:TextEditor %>"
/>
</td>
</tr>
</table>
</td></tr>
<tr><td style="border-color:Black; border-width:1px; border-style:solid;background-color:#FFFFF0;padding: 10px">
<%# ((CommentRecord)Container.DataItem).Text %>
</td></tr>
<tr><td>
<table width="100%"><tr>
<td style="text-align:left">
<asp:Button ID="btnDelete" runat="server" Text="Delete"
CausesValidation="False" />
</td>
<td style="text-align:right">
<asp:Label ID="footer" runat="server" Text="<%# GetFooter((CommentRecord)Container.DataItem) %>" />
</td>
</tr></table>
</td></tr>
</table>
<asp:PlaceHolder ID="placeHolder" runat="server" />
</td></tr>
</ItemTemplate>
</asp:Repeater>
What I usually do in these cases is have Javascript that handles the client-side dynamic creation of additional textboxes, then before I submit the values, have all the data collected into a JSON object and save the JSON string into a <asp:HiddenField> control that ASP.NET can read and parse. This isn't a perfectly clean approach, but it is the best thing I have found so far.
I would create the textboxes using jQuery (assigning them a unique id) and then get the values on the server from the Request.Form key/value collection. This would be a rather simple solution.
I would recommend going the GridView way, and bind it to a DataSource object, e.g. ObjectDataSource. Clicking the add button should add an empty row to the data source, and this empty row will automatically be drawn by the GridView. When everything works you can wrap in an UpdatePanel to achieve smooth refresh when adding rows.

Categories