problems with binding <%# in Custom Control - asp.net

so I've finally started building custom controls instead of using functions which return chunks of HTML ;) But I'm running into a problem. I want to pass parameters to the control, say, "X":
<some:MessageControl runat="server" X=<%# "asd" %> />
My code behind looks like this:
public partial class MessageControl : System.Web.UI.UserControl
{
String x = "";
public String X
{
get { return x; }
set { x = value;}
}
}
When I output the value of x in the control,
x: <%= X %>
it is empty.
If I pass on "asd" directly as in
<some:MessageControl runat="server" X="asd" />
X gets the correct value.
What's happening here? How can I get this to work? Any suggestions are appreciated,
Nicolas
Edit: Some more context. Basically I want to be able to insert the control on a number of pages without settings its properties in the code behind, but still be able to set its visibility by calling a (varying) method from the containing page.
<%# Page Language="c#" Src="MyPage.aspx.cs" AutoEventWireup="true" Inherits="MyPage" %>
<%# Register Src="MessageControl.ascx" TagName="MessageControl" TagPrefix="some" %>
<html>
<body>
<some:MessageControl runat="server" Visible=<%# SomeBoolMethodFromContaining Page%> />
</body>
</html>

For <%= SomeMethods or Property %> expression you need to call DataBind() method in parent page or control that contains this expression on OnPageLoad event or another.
For example here code behind:
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}
protected string Hello
{
get { return "hello";}
}
Here html part of the page:
<asp:Literal runat="server" Id="Literal1" Text="<%= Hello %>"/>
For Visible property use code above and <%# Method or Property%> expression. For text use <%= %> expression. It renders output as a plain text.
Hope it will help you with your question.
Best regards, Dima.

Use this:
X='<%# "asd" %>'
Note the single quotes.

Related

Using Code Nuggets as property values

I have the following code
<asp:Content ID="Content1" runat="server">
<asp:Label runat="server" ID="Label1" Text="<%= MyHelperClass.Value%>"></asp:Label>
<%= MyHelperClass.Value%>
</asp:Content>
The Label doesn't work, it has the Text <%= MyHelperClass.Value%> the next row returns the expected value.
Question: can i use those code nuggets to set values of the property of an control?
Why it's working outside and not with Control?
Well <%= %> is called Content Code Nuggets because they inject content in the html which is sent by server to browser. It does the work of Reponse.Write. We use this mainly to call any code written in code behind file for example, you have a simple method in your code behind:-
public string UserCity()
{
return "London";
}
Then you can call it from aspx page like this:-
You live in <%= UserCity() %>.
Content code nuggets used to inject the html to response at the last in PreRender event and thus it's called late binding. This is the main reason why it is NOT working with your control.
How to fix this?
You can use the data binding code nuggets (<%# %>). These are used with DataBound controls but you can force the Page's DataBound or control's DataBound method to bind your control like this:-
<asp:Label runat="server" ID="Label1" Text="<%# MyHelperClass.Value%>"></asp:Label>
Call DataBind method in code behind:-
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Page.DataBind();
}
}

Call method in ListView EmptyDataTemplate

I have a simple ListView with an EmptyDataTemplate. In the EmptyDataTemplate, there is a LinkButton whose Visble property value is an expression that calls a method in my code behind. The problem is that the LinkButton is always visible regardless of whether the method returns true or false (my method isn't being called as I even set a breakpoint on it). Anyone come across this? What's happening here?
e.g.
<asp:ListView ID="peopleListView" runat="server" ...>
...
<EmptyDataTemplate>
Sorry, no people to view.<br />
<asp:LinkButton ID="newButton" runat="server" Visible='<%# EditPermitted() %>'>New Record</asp:LinkButton>
</EmptyDataTemplate>
</asp:ListView>
In the code behind, I have the method:
protected bool EditPermitted()
{
return false;
}
I don't think you can put scriplets <% %> inside of server controls.
You need to grab the RowDataBound event, and set the link button's visibility there
void gridView1_RowDataBound(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.EmptyDataRow) {
LinkButton lb = e.Row.FindControl("newButton");
lb.Visible = EditPErmitted();
}
}
You can't use code blocks like <% ... %> or <%= ... %> inside the attributes of server controls. Only data binding blocks like <%# ... %>. But you can use code blocks inside your EmptyDataTemplate, in this case a simple if statement should work:
<EmptyDataTemplate>
<% if(EditPermitted()) { %>
<asp:LinkButton ID="newButton" runat="server" ... />
<% } %>
</EmptyDataTemplate>

I want to get property value from code behind

I have a case that I need to set the Text property for an asp label in the aspx page not from code behind. More exactly, I need to set a value to asp control in aspx page and this value is set by a property in the same page code behind.
so I need to use an expression to do that like:
<asp:Label Text="<%= MyProperty %>" ..../>
I use:
<%= MyProperty %> doesn't work.
<%# MyProperty %> doesn't also.
Default.aspx.cs
public partial class _Default : System.Web.UI.Page
{
public string CustomTitle = "This Is Title";
protected void Page_Load(object sender, EventArgs e)
{
Page.DataBind();
}
}
Default.aspx
<asp:Label Text='<%#CustomTitle %>' runat="server" />
You have to treat regular HTML and WebControls differently:
regular HTML:
Using <%= ... %> is sufficient:
<span><%= MyProperty %></span>
WebControls (stuff starting with <asp:...>):
<asp:Label Text='<%# MyProperty %>' />
In this case, you also have to call Me.DataBind() (VB) or this.DataBind(); (C#) in your codebehind, since <%# ... %> are data binding expressions.
Page.DataBind();
Do you call this in your code? It binds all variables set in code to your page.

Assigning Visible Property of the Button to a Static Method Result

I am trying to hide the button based on the user's role using the following code:
<asp:Button ID="btndisplayrole" Text="Admin Button" Visible='<%= WebApplication1.SiteHelper.IsUserInRole("Admin") %>' runat="server" OnClick="DisplayRoleClick" />
But when I run the above code I get the following error message:
Cannot create an object of type 'System.Boolean' from its string representation '<%= WebApplication1.SiteHelper.IsUserInRole("Admin") %>' for the 'Visible'
Kind of an interesting issue.. But as the error message states, the string <%= WebApplication1.SiteHelper.IsUserInRole("Admin") %> cannot be converted to a boolean.
Unfortunately i cannot explain why the expression isn't evaluated, but instead is treated like a string.
The reason why your <%# %> expression works as expected, is because it is treated much differently. When the Page is compiled into a class, then the compiler creates an event handler similar to this:
public void __DataBindingButton2(object sender, EventArgs e)
{
Button button = (Button) sender;
Page bindingContainer = (Page) button.BindingContainer;
button.Visible = HttpContext.Current.User.IsInRole("admin");
}
and hooks this method up to the Control.Databinding event on your control. As you can see, the <%# %> is this time properly treated as server code, and not just a random string.
So i guess the solution is either to use databinding, or go to the codebehind as AndreasKnudsen suggests.
As an alternative solution:
<% if (WebApplication1.SiteHelper.IsUserInRole("Admin"))
{%>
<asp:Button ID="btndisplayrole"
Text="Admin Button"
runat="server"
OnClick="DisplayRoleClick" />
<%} %>
The following code worked:
Visible='<%# WebApplication1.SiteHelper.IsUserInRole("Admin") %>'
Note that the aboe use the binding expression!
how about just doing it in the codebehind, for instance on Page_Load ?
public void Page_Load( object sender, EventArgs e )
{
btndisplayrole.Visible = WebApplication1.SiteHelper.IsUserInRole("Admin");
}
Visible='<%= WebApplication1.SiteHelper.IsUserInRole("Admin").ToString() %>'
OR
Visible=<%= WebApplication1.SiteHelper.IsUserInRole("Admin") %>

Is it possible to use Data-Binding Expressions directly in markup to show/hide content?

I would like to do something like:
<%# if((bool)Eval("IsDisabled")){ %><span>Disabled</span><% }
else { %><span>Active</span><% } %>
but I don't think its possible.
There is a way to create method in codebehind which returns appropriate string and call it, but thats not an option.
You can use placeholders to hold the two versions of your markup and then use the Visible property to show the relevant one. Something like this... Note the use of ! before the call to IsDisabled in the second Visible property.
<asp:PlaceHolder ID="PlaceHolder1" runat="server" Visible='<%# IsDisabled((bool) Eval("IsDisabled")) %>'>
<span>Disabled</span>
</asp:PlaceHolder>
<asp:PlaceHolder ID="PlaceHolder2" runat="server" Visible='<%# !IsDisabled((bool) Eval("IsDisabled")) %>'>
<span>Active</span>
</asp:PlaceHolder>
The code behind IsDisabled method looks like this...
public bool IsDisabled (bool isDisabled)
{
return isDisabled;
}
Its not possible to use # eval in if statement,
You have some options to solve that:
You can put the condition of the if in a previous line then check on this variable in the if
example:
in code behind:
protected bool isDisabled;
in aspx:
<%# isDisabled=(bool)Eval("IsDisabled") %>
<% if(isDisabled) %>
Other way is to call a code behind method which return bool and check on it in the if.

Resources