Why can not use <%=...%> in the ListView - asp.net

All, Generally .If we want to output a variable in a page which defined in the code-behind class file of page . We could set the variable with public or protect visibility. and in the front page we can use it like below.
<%=VariableName%>.
But I don't know why can't use it in the ListView. Please help to review my code.
In the front page
<div id="divIssuedListContainer" class="myIssuedList">
<asp:ListView id="listShower" runat="server">
<LayoutTemplate>
<div id="divIssuedListHeadTitle">
<div id="divIssuedListTitleIco">
<img alt="" src="ico/IssuedCap.png" />
</div>
<div id="divIssuedListTitleName">
<span>ISSUED</span><span>TRADE NAMES</span><span>/LICENSES</span>
</div>
<div id="divIssuedListItemNumber">
<span>
<%=iListNumber%></span>
</div>
</div>
<div style="clear:both"></div>
<div id="divIssuedListBody">
<ul>
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</ul>
</div>
</LayoutTemplate>
<ItemTemplate>
<li>
<table>
<tr>
<td>
<img alt="" src="" />
</td>
<td>
<div>
<span>
<%# Eval("altID") %>
-
<%# Eval("englishTradeName") %></span></div>
<div>
<span>Expired Date:<%# Eval("expDate") %></span>
</div>
</td>
</tr>
</table>
</li>
</ItemTemplate>
</asp:ListView>
In the code-behind of page
public partial class _Default : System.Web.UI.Page
{
protected int iListNumber = 0;
protected void Page_Load(object sender, EventArgs e)
{
List<SimpleCapModel> DataSourceList = TestDataHelper.GetMyIssuedList();
listShower.DataSource = DataSourceList;
iListNumber = DataSourceList.Count();
listShower.DataBind();
}
}
I got an error page said :
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
Source Error:
Line 19: listShower.DataSource = DataSourceList;
Line 20: iListNumber = DataSourceList.Count();
Line 21: listShower.DataBind();//this line cause error.
Line 22: }
Line 23: }
And If I use the expression <%#iListNumber%>. The error is gone, but I got a empty value instead of the number of the list. please review below rendered result html :
<div id="divIssuedListItemNumber">
<span> </span>
</div>
I didn't know whether I missed something ? If I did .Please help to let me know it.thanks.

You need to use <%#iListNumber %> because you are using data-binding the ListView, otherwise you'll get the exception (see: http://support.microsoft.com/kb/976112 for more on inline expressions).
Try using <%#iListNumber.ToString %> and see if that makes a difference.
UPDATE:
The problem appears to be that your inline-expression is in the LayoutTemplate, where data-binding [apparently] won't work without either handling the OnLayoutCreated event, or extending the ListView.
See either of the following for examples of how to extend the ListView:
http://www.codeproject.com/Articles/42962/Databind-Expression-in-ListView-LayoutTemplate
http://forums.asp.net/p/1201992/3319344.aspx#3319344

Given the error you're receiving, it basically means this: you can't just randomly throw .NET tags in databound controls.
The solution is to, instead, throw that random text in a .NET control, like this: <asp:Literal Runat="server" Text="<%# iListNumber %>" />
When you put a .NET codeblock in code, it dynamically has to build a control placeholder for it. It's a little tricky. But if you wrap all your custom tags up in a control, then just that one property gets databound and the databound block remains "clean" if that makes sense.

Related

Change id of elements in ContentPlaceHolder

I use masterpage in asp.net web form, I use span to display message to users
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder2" runat="server">
<div class="col-md-10 col-sm-10">
<span id="spnMessage" class="btnText" runat="server"></span>
</div>
</asp:Content>
and code is:
spnMessage.InnerText = "Add record successfully ";
but in runtime id of span change to "ContentPlaceHolder2_spnMessage" and my code does not work. What should I do?
Change the span into a Literal. Then there will be no more issues with ID conflicts.
<asp:Literal ID="spnMessage" runat="server"></asp:Literal>
Then accessing the Literal from code behind will always work.
spnMessage.Text = "Add record successfully ";
Or if you need to use the <span> element for CSS purposes, you can still wrap the Literal with it.
<span><asp:Literal ID="spnMessage" runat="server"></asp:Literal></span>
You could also use a aspnet Label.
A label will generate it's own <div> tag in HTML.
<asp:Label ID="spnMessage" runat="server" Text="Add record successfully"></asp:Label>
Will become
<div>Add record successfully</div>

why it says there are not my text boxes

i wrote below code . but i do not know why i get error. but every thing seems ok.
it says there are not my text boxes in context. but there are .
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<form id="form1" runat="server">
<asp:TextBox ID="address" runat="server"/>
<div class="form1">
<label for="fname">
<span>name:</span>
<asp:TextBox ID="fname" runat="server"/>
</label>
<label for="lname">
<span>lname: </span>
<asp:TextBox ID="lname" name="lname" runat="server" />
</label>
.
.
.
</div>
protected void send2_Click(object sender, EventArgs e)
{
tbl_register tbl = new tbl_register();
tbl.firstname = fname.Text; // The name 'fname' does not exist in the current context
tbl.lastname = lname.Text; // The name 'lname'does not exist in the current context
tbl.address = address1.Text; //..
tbl.phone = phone.Text; //..
tbl.email = email3.Text; //..
db.tbl_registers.InsertOnSubmit(tbl);
db.SubmitChanges();
}
The textboxes as coded are children of the label. I do not code my lables in that way. In order to use controls that are child controls you must use Control.FindControl, in this case fname.FindControl("fname"). I would not name controls the same as other controls. You can also close the label tag such that it does not enclose those controls, and then the control can be referenced via the name.
the line
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
suggests that this is a webform that uses a MasterPage.
inside the content place holder you have a form declaration that runs at server:
<form id="form1" runat="server">
however, on your MasterPage.master you already have a form that runs at server that wraps the content placeholder.
asp.net does not allow 2 nested forms to both run at server.

repeater how to avoid blank html

We currently have an application which we have a repeater
<asp:Repeater ID="rptOfficials" runat="server">
<ItemTemplate>
<tr>
<td>
<p class="officials">
<%#Eval("OffPosition") %> <%#Eval("FullName") %>
</p>
<p class="officials">
<%#Eval("Phone") %>
</p>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
The Phone field is not always supplied, when not there a blank paragraph tag is generated, we're thinking of changing
<p class="officials">
<%#Eval("Phone") %>
</p>
to either:
<p class="officials">
<asp:label id="lblPhone" runat="server"/>
</p>
or:
<p class="officials">
<%#GetPhone("OffId") %>
</p>
and then have either the label return the phone number with the paragraph tags wrapped around it, or have the function return it. Is there a better way to get around this?
It depends how your Binding model is composed but I suggest adding the logic in your property (Phone) on your page your (view)model (yes you can and should use ViewModels in web forms as well).
That way you keep logic outside the view.
public string Phone {
get {
return this.phone ?? string.Empty;
}
}
That way your logic stays nicely inside your view model and your view just takes care of binding it.
If you don't want to generate the -tag, you can add a boolean property to your model.
public bool DisplayPhone{
get {
return this.Phone == string.Empty;
}
}
You then need to bind it to the visible property as Halcyon mentioned. (note you need a runat="server" for this)
<p runat="server" class="officials" visible='<% #Eval("DisplayPhone") %>'>
<% #Eval("Phone") %>
</p>
I would not recommend using "display: none" since it will keep the space of the p tag. Instead, make the p tag a server tag and set its visibility to false.
<p runat="server" class="officials" visible='<% !string.IsNullOrEmpty(#Eval("Phone")) %>'>
<% #Eval("Phone") %>
</p>
Instead of using
<p class="officials">
<%#GetPhone("OffId") %>
</p>
I prefer generate <p class="officials">foo</p> inside GetPhone(), then you can return nothing when Phone is empty.
You can add small logic like the following -
<%# string.IsNullOrWhiteSpace(Eval("Phone").ToString()) ?
"" : ("<p class=\"officials\">" + Eval("Phone") + "</p>")%>
However, if you want to add more logic, I would like to suggest to use Repeater.ItemDataBound Event
try with this
<p class="officials" <%#string.IsNullOrEmpty(Eval("Phone").ToString())? "style='display:none;':''" %> >
<%#Eval("Phone") %>
</p>

usercontrols with variably named elements

I've been reading about user controls on msdn, and I was wondering how does one deal with element IDs that may be variable?
For example, say I have usercontrol1.ascx on my page that contains this:
<div id="myPageDiv1">
<div id="container1">
Contents
</div>
</div>
What if I need the IDs to be different across different pages?
Maybe I need another page that needs to look like this:
<div id="myPageDiv2">
<div id="container3">
Contents
</div>
</div>
Thanks
You could add a property to your usercontrol so you can change it on a page-by-page basic:
UserControl
Public Property SomeDivID as String
ASPX
<div id="<%= Me.SomeDivID %>">
</div>
Page
<control:yourusercontrol SomeDivID="myPageDiv1" runat="server" />
<control:yourusercontrol SomeDivID="myPageDiv2" runat="server" />
You can define a property in your user control.
Public Property DivName As String
You can set it in your codebehind to your desired name. You can even pass this from your controlling page.
DivName = "MyDesiredDivName"
Then you can use crocodile syntax in your markup to render the value of the property.
<div id="<%= Me.DivName %>">
<div id="container1">
Contents
</div>
</div>

ASP.NET Repeater Eval

I am trying to execute the following code in a .aspx page:
<asp:Repeater ID="rptComentarios" runat="server">
<ItemTemplate>
<% if (Convert.ToInt32(Eval("int_tipo")) == 1)
{ %>
<div class="resp">
<div class="top">
</div>
<div class="cont-resp">
<h3>
<%# Eval("txt_nome") %></h3>
<p>
<%# Eval("txt_comentario") %></p>
</div>
</div>
<% }
else
{%>
<div class="usuario">
<div class="top">
</div>
<div class="cont-usuario">
<h3>
<%# Eval("txt_nome") %></h3>
<p>
<%# Eval("txt_comentario") %></p>
</div>
</div>
<% } %>
</ItemTemplate>
</asp:Repeater>
It throws a runtime exception in the first line:
<% if (Convert.ToInt32(Eval("int_tipo")) == 1)
System.InvalidOperationException: Databinding methods such as Eval(), XPath() and Bind() can only be used in the context of a databound control.
What's wrong? Any ideas?
I had a similar problem and the following code worked for me:
<asp:Repeater ID="rptComentarios" runat="server">
<ItemTemplate>
<asp:PlaceHolder ID="placeholderBlaBlaBla" runat="server" Visible='<%# Convert.ToInt32(Eval("int_tipo")) == 1 %>'>
Your optional HTML
</asp:placeholder>
Other HTML
</ItemTemplate>
</asp:Repeater>
Some more comments:
Please note that single quotes are used to define the value Visible attribute of asp:placeholder. I tried double quotes too and they didn't work.
Anytime you want to get some optionally displayed HTML you should use a control to show/hide it. asp:placeholder works fine for that purpose. Don't ever do <% if(..) { %> - this is evil.
<%# ... %> is used to calculate or display expressions inside a repeater. These expressions can be displayed as HTML or passed as attributes of server side controls. You can't use if inside it.
I think there needs to be a # sign for the enclosure <%# ..Eval...%>
Or try the full Eval version
<%# if (Convert.ToInt32(DataBinder.Eval(Container.DataItem, "int_tipo"))
== 1) { %>

Resources