extension method in gridview eval - asp.net

I have an extension method that I wrote but when I use it on an aspx page to render a label inside a gridview, it doesn't work.
<asp:Label ID="lblStatus" runat="server" Text='<%# Eval("TheStatus").ToMyStatus() %>'></asp:Label>
The extension method is a file called Appfunctions.cs:
public static class Extensions
{
public static string ToMyStatus(byte TheStatus)
{
//mycode
}
}
I've seen posts that say a namespace needs to be added with the Imports statement in the aspx page but the extention ToMyStatus is not in any particular namespace.
Any suggestions much appreciated.
Thanks.

You have missed this and type conversion.
public static class Extensions
{
public static string ToMyStatus(this byte TheStatus)
{
return "Hello : " + TheStatus;
}
}
Markup
<asp:Label ID="lblStatus"
runat="server"
Text='<%# ((byte)Eval("TheStatus")).ToMyStatus() %>'>
</asp:Label>

Related

Why my asp:Literal control doesn't work in a asp:ListView ItemTemplate

Why my asp:Literal control doesn't work in a asp:ListView ItemTemplate ?
ASP.NET 4.5 WebForms
ASPX code :
<asp:ListView ID="lv" runat="server" ItemType="WebApplication1.ItemClass">
<ItemTemplate>
<asp:Literal runat="server" Text='<%#: Item.HtmlText %>' />
</ItemTemplate>
</asp:ListView>
ASPX code behind :
this.lv.DataSource = new ItemClass[] {
new ItemClass() { HtmlText = "<p>Hello 01<br/>blablabla</p>"},
new ItemClass() { HtmlText = "<p>Hello 02<br/>blablabla</p>"},
new ItemClass() { HtmlText = "<p>Hello 03<br/>blablabla</p>"}
};
this.lv.DataBind();
My object class :
public class ItemClass
{
public string HtmlText { get; set; }
}
Result on my page :
<p>Hello 01<br/>blablabla</p> <p>Hello 02<br/>blablabla</p> <p>Hello 03<br/>blablabla</p>
I can see html elements tags. I don't known why.
Thanks
When you use the colon character (:) in your code block, it automatically HTML encodes the output. (see my answer here for more information)
To fix this, simply drop the colon from your code, so it looks like this instead:
<asp:ListView ID="lv" runat="server" ItemType="WebApplication1.ItemClass">
<ItemTemplate>
<asp:Literal runat="server" Text='<%# Item.HtmlText %>' />
</ItemTemplate>
</asp:ListView>

asp:label doesn't render children

I have an asp:label with a nested custom control and it simply doesn't render. I tried to register a custom WebControlAdapter for Label type and while debugging I noticed that there is apparently no control in the Controls collection, it seems to be completely ignoring any nested elements.
Here's markup
<asp:Label ID="lbl13" runat="server" AssociatedControlID="txt13" Text="<%$ Resources:Resources, lbl13 %>">
<asp:ValidationMessage ID="vm13" runat="server" MessageFor="txt13" CssClass="field-validation-error"></asp:ValidationMessage>
</asp:Label>
Any idea how to bypass this problem?
When you set the Text property, it clears the child controls. If you remove the Text="<%$ Resources:Resources, lbl13 %>" from the Label, your child controls should render.
EDIT
If you set the Text property to a static string and add only literal content, the label will only render the literal content:
<asp:Label runat="server" Text="Hello"> World</asp:Label>
Output: World
If you set the Text property to a static string and add child controls, the label will render the text and the child controls:
<asp:Label runat="server" Text="Hello">
<asp:Label runat="server" Text="World" />
</asp:Label>
Output: HelloWorld
If you set the Text property using an expression builder, the label will only render the text:
<asp:Label runat="server" Text="<%$ Resources:Resources,Hello %>">
<asp:Label runat="server" Text="World" />
</asp:Label>
Output: Localised version of "Hello"
To override this behaviour, you'll need a custom Label control. For example:
public class MyLabel : Label
{
public override string Text
{
get { return base.Text; }
set
{
if (HasControls())
{
Controls.AddAt(0, new LiteralControl(value));
}
else
{
base.Text = value;
}
}
}
}

How to call a code-behind method from aspx page?

I've an object that contains a field called DevList which is defined like this
public List<string> DevList { get; set; }
I also defined a method called DisplayListOfDevelopers that is supposed to concatenate the list of developers and display it as a one string.
This is how I'm calling the method from aspx.
<asp:TemplateField HeaderText = "Developer(s)">
<ItemTemplate>
<asp:Label
ID="_lblDevList"
runat="server"
Text= '<%# DisplayListOfDevelopers(DevList) %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
But, I'm getting this error: The name 'DevList' does not exist in the current context
Am I missing something?
EDIT
_gvStatus = ds;
_gvStatus.DataBind();
Where ds is just a list of objects that contains the DevList for now.
Thanks for helping
Assuming this is how your class looks:
public class MyItem
{
public List<string> DevList { get; set; }
}
And that
ds = List<MyItem>();
Do this:
In your code-behind:
protected string DisplayListOfDevelopers(object _devList)
{
//Cast your dev list into the correct object
}
In your markup:
<asp:TemplateField HeaderText="Developer(s)">
<ItemTemplate>
<asp:Label
ID="_lblDevList"
runat="server"
Text='<%# DisplayListOfDevelopers(Eval("DevList")) %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
Just be sure to make the function in your code-behind is protected or public.

Bind value of property to result of some method in ASP.NET

I need to bind an ASP.NET control something like so:
<asp:label ID="lblName" Text=<%# GetName()) %>
and in CodeBehind file I have this method:
protected string GetName()
{
...
}
Is this right, or how I can do something like this?
Methods in code-behind need to be public I believe; I could be wrong, but I've gotten this to work:
<asp:label ID="lblName" Text='<%= GetName() %>' />
With
public string GetName()
{
...
}
HTH
Try:
<asp:Label ID="Status" runat="server"><%# this.Test() %></asp:Label>
The above code assumes that you have a method called Test() with public access that returns a string in its implementation file.

Is there any way to declaratively pass code-behind property values to server controls?

Can anyone explain why you can’t use inline code blocks within server control declarations in ASP.Net?
The following is a simple example...
....
<form id="form1" runat="server">
<asp:Label ID="Label1" runat="server" Text="<%= SomeProperty %>"></asp:Label>
</form>
....
The code block is rendered literally to the page...
<span id="Label1"><%= SomeProperty %></span>
My initial thoughts are it has to do with the order that these things are processed in the page life-cycle. The <%=...%> blocks are, as I understand it, equivalent to a Response.Write(...) in code-behind. And since the server control is not actually rendered as declared in the markup, I suppose it may not be possible to process an embedded code block before this rendering takes place.
I would be very grateful of anyone could explain that a little better.
However, the data binding code block <%#...%> is obviously different in the way it behaves, but can anyone tell me why it is possible to embed these within a server control...
....
<asp:Repeater id=Repeater1 runat="server">
....
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval(“SomeProperty”) %>'></asp:Label>
</ItemTemplate>
....
</asp:Repeater>
....
This works fine.
You're mostly right about the <%=...%> syntax.
Here is an example of what happens under the hood:
<script runat="server">
public string SomeProperty { get { return "Hello World!"; } }
</script>
<form id="form1" runat="server">
<%= SomeProperty %>
<div>
<asp:Label ID="Label1" runat="server" Text="<%= SomeProperty %>"></asp:Label>
</div>
</form>
This is parsed and the following C# code is created (I've simplified it a bit):
private Label #__BuildControlLabel1()
{
Label #__ctrl = new Label();
this.Label1 = #__ctrl;
#__ctrl.ApplyStyleSheetSkin(this);
#__ctrl.ID = "Label1";
#__ctrl.Text = "<%= SomeProperty %>";
return #__ctrl;
}
private void #__Renderform1(HtmlTextWriter #__w, Control parameterContainer)
{
#__w.Write( SomeProperty );
#__w.Write("\r\n <div>\r\n ");
parameterContainer.Controls[0].RenderControl(#__w);
#__w.Write("\r\n </div>\r\n ");
}
Here is an example of what happens under the hood for the <%#...%> syntax:
<script runat="server">
public string SomeProperty { get { return "Hello World!"; } }
protected void Page_Load(object sender, EventArgs e) { Label1.DataBind(); }
</script>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="<%# SomeProperty %>"></asp:Label>
</div>
</form>
Generates this code:
private Label #__BuildControlLabel1()
{
Label #__ctrl = new Label();
this.Label1 = #__ctrl;
#__ctrl.ApplyStyleSheetSkin(this);
#__ctrl.ID = "Label1";
#__ctrl.DataBinding += new System.EventHandler(this.#__DataBindingLabel1);
return #__ctrl;
}
public void #__DataBindingLabel1(object sender, EventArgs e)
{
Label dataBindingExpressionBuilderTarget = ((Label)(sender));
Page Container = ((Page)(dataBindingExpressionBuilderTarget.BindingContainer));
dataBindingExpressionBuilderTarget.Text = System.Convert.ToString( SomeProperty , System.Globalization.CultureInfo.CurrentCulture);
}
As you can see the <%=...%> syntax can be used outside of a server control's properties to directly render the returned value. On the other hand the <%#...%> syntax generates a event handler for the DataBinding event of the label. This event sets the value of the label's property to the value of SomeProperty. The DataBinding event fires whenever the DataBind method is called which is why I added that call to the Page_Load event.
Hopefully this will help you understand the difference between them.
You could create a custom ExpressionBuilder so you use something like <%$ Code: SomeProperty %>
You can create a custom databound control, e.g.
namespace FooBar.WebControls
{
public class DataBoundPlaceHolder:PlaceHolder
{
private bool hasDataBound = false;
protected override void CreateChildControls()
{
if (!hasDataBound)
{
this.DataBind();
hasDataBound = true;
}
base.CreateChildControls();
}
}
}
Then wrap your code in this new control, and use the <%# %> syntax, e.g.
<%# Register TagPrefix="WebControls" Namespace="FooBar.WebControls" Assembly="FooBar" %>
<form id="form1" runat="server">
<WebControls:DataBoundPlaceHolder runat="server">
<asp:Label ID="Label1" runat="server" Text='<%# SomeProperty %>'></asp:Label>
</WebControls:DataBoundPlaceHolder>
</form>

Resources