Dynamically assigning properties on a non data bound ASP.NET control - asp.net

For example, let's say I have a HyperLink:
<asp:HyperLink runat="server" Text="Foo" NavigateUrl="foo.aspx" />
How can I set the NavigateUrl on the server side, without having to go the code-behind?
This doesn't work of course:
<asp:HyperLink runat="server" Text="Foo" NavigateUrl="<%= urlString %>" />
(where urlString might be a string I created earlier in the page)
And this doesn't work because the HyperLink is not within a data bound control:
<asp:HyperLink runat="server" Text="Foo" NavigateUrl='<%# urlString %>' />
I guess I could just use a standard anchor element:
Foo
But I'd rather not mix up HTML and ASP.NET controls, and it would be handy to be able to do this for other controls.
Surely there must be a way?

Try setting the property in an inline code block:
<asp:HyperLink runat="server" ID="MyLink" Text="Foo" />
<% MyLink.NavigateUrl="foo.aspx"; %>

This doesn't work of course:
Of course it does.
And this doesn't work because the
HyperLink is not within a data bound
control:
Consider the Page as your data bound control.
You need to calls it's DataBind method.
Page.DataBind();
Maybe you need to add an ID attribute as well. If that does not work, try to display a property instead of a variable.

Related

asp:hyperlink href won't show up even though i populate navigateurl

Does anyone know what is wrong with the following two lines of code? In both cases, there is no href in the anchor links when i view it in the browser:
<asp:HyperLink runat="server" NavigateUrl='<%# Eval(Request.QueryString["conferenceId"], "~/Cms/schedule-edit.aspx?conferenceId={0}&type=workshopStream") %>' Text="Create Workshop Stream"></asp:HyperLink>
<asp:HyperLink runat="server" NavigateUrl='<%# String.Format("~/Cms/schedule-edit.aspx?conferenceId={0}&type=scheduleItem", Request.QueryString["conferenceId"]) %>' Text="Create Schedule Item"></asp:HyperLink>
This exact same code seems to work fine when I put it into the ItemTemplate of a Listview though. But it doesn't work when used on it's own in an aspx file.
What's wrong with it?
Also if i replace the navigateUrl with a hardcoded string ~/cms/schedule-edit.aspx?conferenceId=2&type=stuff then the href shows up. It just doesn't work when i have the Eval or String.Format in there.
If those HyperLink server controls are located outside of DataBound controls like GridView, there are two problems in our code -
You want to use <%= %> instead of <%# %> which is used in DataBound controls.
You cannot use <%= %> to set property of a server control. Basically, you cannot mix runat="server" with <%= %>.
Solution
<a href='<%= String.Format("~/Cms/schedule-edit.aspx?conferenceId={0}&type=scheduleItem",
Request.QueryString["conferenceId"]) %>'>Create Workshop Stream</a>
The anchor syntax NavigateUrl='<%#...%> is only valid inside a GridView, ListView, etc. When it is not inside such controls, you can set its NavigateUrl property via code. Obviously, you also need to give an ID to your HyperLink.
The markup:
<asp:HyperLink ID="HyperLink1" runat="server" Text="Create Schedule Item"></asp:HyperLink>
The code behind:
HyperLink1.NavigateUrl = String.Format("~/Cms/schedule-edit.aspx?conferenceId={0}&type=scheduleItem", Request.QueryString["conferenceId"])
You are using a data-binding expression here. This is denoted in the following syntax:
<%# [code] %>
The code inside is evaluated only when the containing control, or any of its ancestors have their .DataBind() method called.
To work this around, you can:
Call Page.DataBind()
This could have some unwanted consequences if you have other data-bound controls on the page, as this method will cause all of them to have their data-binding events fired. Usually, this approach is applied if you have minimalistic code-behind and the entire page relies on data-binding expressions.
Give each HyperLink an ID and call HyperLinkID.DataBind();
Stick to the approach in codingstill's answer by setting the NavigateUrl property in the code behind of your page/user control.

Why can't controls in Templates be referenced via their parent?

I've been wondering to why you have to use FindControl to reference the checkbox in the Login1's LayoutTemplate. Example:
var login1CheckBox1 = (CheckBox)Login1.FindControl("CheckBox1");
I would expect to be able to do something along the lines of:
var login1CheckBox1 = Login1.LayoutTemplate.CheckBox1;
In the case of the Repeater below, it is obvious, because there can be n number of CheckBoxes.
But for the Login control, it doesn't seem to make sense. Why wouldn't this be implemented differently?
<asp:Login ID="Login1" runat="server">
<LayoutTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</LayoutTemplate>
</asp:Login>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:Repeater>
Does anyone have any light to shine on this?
A control added to a page via markup is defined in the designer partial class, generally, at design time.
A control added to a template is generally instantiated programmatically within the control's collection of controls.
Since the control added to the template does not exist at compile-time in the definition of that control, it would be rather impossible to achieve the syntax you're aiming for.
When creating a page in markup, we're using the IDE's facilities to generate a partial class. When defining a template in markup, we're simply setting the value of the ITemplate for that control.

ASP.NET server tags rendered in client HTML, not values?

Maybe I've forgotten how to use these, but I am going crazy trying to inject a server-side value into an HTML output. There are reasons why I am doing this inline, and not server-side, so please don't suggest that as a solution.
This code on the server side:
<asp:Label ID="Label1" runat="server" Text='<%= DateTime.Now.ToString() %>' />;
Renders as this in the client HTML sent to the browser:
<span id="Label1"> <%= DateTime.Now.ToString()></span>;
And it displays as big fat empty space, and nothing output to the interface.
If I change the ASP source to using the "#" character to define as data-binding syntax, then the rendered output to browser becomes:
<span id="Label1"></span>
EDIT:
Setting Label text was just a simplified object for the sake of asking the question. In real life, I am setting the CssClass attribute, which does not allow me to use the "wrapping" workaround some have suggested. I wanted to set a public property and have all the controls update from it dynamically on page load.
Ideally, since I already have all the controls laid out on the aspx page. Just looking to add an attribute. I wanted to have:
<asp:textbox ID='MyTxtBox1' CssClass='<% strVal1 %>' />
<asp:textbox ID='MyTxtBox2' CssClass='<% strVal1 %>' />
<asp:textbox ID='MyTxtBox3' CssClass='<% strOtherVal %>' />
<asp:textbox ID='MyTxtBox4' CssClass='<% strVal1 %>' />
Now what it looks like I need to do is repeat all my (250+) controls on the codebehind in a block of code that looks like:
MyTxtBox1.CssClass=strVal1
MyTxtBox2.CssClass=strVal1
MyTxtBox4.CssClass=strVal1
MyTxtBox3.CssClass=strOtherVal
I believe that may not work on a compiled Web Application as it's not interpreted at run-time like a C# "Web Site". However, I was able to get it to work wrapping the label around the value:
<asp:Label runat="server"><%= DateTime.Now.ToString() %></asp:Label>
Set the Label1.Text = value instead of trying to use server side attrs inside of the server control

Override FormView Templates

By default the FormView control creates html like :
ID <asp:TextBox ID="IdTextBox" runat="server" Text='<%# Eval("ID") %>' />
<br />
Name <asp:TextBox ID="NameTextBox" runat="server" Text='<%# Eval("Name") />
I prefer:
<ol class="form-layout">
<li><asp:Label AssociatedControl="IdTextBox" runat="server">ID:</aspLabel><asp
....
</ol>
My plan is to create a new control ( OrderedListFormView ) that inherits the FormView and overrides the method that generates the default "crap" html. I have been unable to find the method. Can anyone help? Do you have a better solution that costs $0 dollars?
I would prefer to change the default behavior at design time.
You sound like you have the ASP.NET form blues. Have you tried ASP.NET MVC? It gives you far better control of your rendered HTML, and you can mix it in with existing ASP.NET applications.
Try using Control Adapters to change the rendered HTML from a FormView, there is a tool kit and are pretty easy to code
http://weblogs.asp.net/scottgu/archive/2006/09/08/CSS-Control-Adapter-Toolkit-Update.aspx
http://msdn.microsoft.com/en-us/magazine/cc163543.aspx

asp:HyperLink build NavigateUrl within Repeater using XPATH data

I am using a repeater for some products I am listing.
I'm trying to build an asp:HyperLink NavigateUrl using both hardcoded text as well as XPATH data.
NavigateUrl='mypage.aspx?ID=<%#XPath("THEID")%>&name=<%#XPath("THENAME")%>'
Obviously this isn't working.
Does anyone know how to make this work?
This should work:
<asp:HyperLink
runat="server"
NavigateUrl='<%# string.Format("mypage.aspx?ID={0}&name={1}", XPath("THEID"), XPath("THENAME")) %>'
Text="some link"
/>

Resources