I'm sure I've done this before, but can't remember the syntax. How do I include a session variable in nagivateUrl in a hyperlink?
I've tried this:
<asp:HyperLink ID="lnkMyLink" runat="server" Text="My Link"
NavigateUrl='<%# "http://absoluteURL.org?param=" +
Session["myParameterValue"].ToString()%>'></asp:HyperLink>
and this:
<asp:HyperLink ID="lnkMyLink" runat="server" Text="My Link"
NavigateUrl='<%# String.Format("http://absoluteURL.org?param={0}",
Session["myParameterValue"].ToString()) %>'></asp:HyperLink>
Because you've used the data binding format (<%#), you need to call the HyperLinks .DataBind() method from your codebehind.
You need your Page_Load method to look something like this:
protected void Page_Load(object sender, EventArgs e)
{
lnkMyLink.DataBind();
}
The only thing to bear in mind that using Data Binding for something like this, i.e. not specifically Data Binding, may be a bit confusing for anyone who has to maintain your code in the future. Whilst it'll be fairly quick and easy to determine what you've done and why you've done it, anything that can cause future confusion should be removed from your code where posible. Therefore a potentially better option would be to put the following in your Page_Load:
lnkMyLink.NavigateUrl =
string.Format("http://absoluteURL.org?param={0}", Session["myParameterValue"]);
If your link is not in a data-bound control, such as a ListView, you can still force databinding (per your first code snippet) by calling .DataBind() on the control from code-behind.
Related
Using ASP.NET 4.0
Bit of a strange one here, my code works but I don't know why!
So I have some HTML like so:
<asp:Repeater runat="server" ID="uxMyRepeater" ClientIDMode="Predictable">
<ItemTemplate>
<asp:Button runat="server" Text="Submit" />
<asp:HiddenField runat="server" ID="uxIsVisibleHiddenField" Value="0" />
</ItemTemplate>
</asp:Repeater>
And the back end:
Protected Sub uxMyRepeater_ItemCommand(source As Object, e As RepeaterCommandEventArgs) Handles uxMyRepeater.ItemCommand
uxIsVisibleHiddenField.Value = "1"
End Sub
So for some reason this works, usually I would expect to have to declare uxIsVisibleHiddenField in uxMyRepeater_ItemCommand like so:
Dim uxIsVisibleHiddenField As HiddenField = DirectCast(e.Item.FindControl("uxIsVisibleHiddenField"), HiddenField)
But in this particular case it works without the declarative statement. Can anyone shed any light on why it would do this?
Please note this is sample code only, not my actual code.
EDIT
Forgot to mention there is an UpdatePanel around each RepeaterItem, removing this causes Visual Studio to give me an error that'd I'd expect: 'uxIsVisibleHiddenField' is not declared. It may be inaccessible due to its protection level.
This could only happen if you have a control with the same ID that sits outside of the repeater. You won't have ID clashes because the repeater is a naming container.
Do you have any AlternatingItemTemplate ? It might be declared in that particular area and remained unnoticed.
After a lot of debugging the only thing I can say is that when I have an UpdatePanel inside the Repeaters ItemTemplate I don't need to declare the controls inside the ItemTemplate when accessing them in the DataBind event, very strange. Taking out the UpdatePanel causes complier errors so the UpdatePanel must be doing some auto hook-up between the Repeater and the controls.
Thanks for all your suggestions.
I have a UserControl that takes a class object as property "DataSource." On DataBind, I apply properties of that object to controls -- TextBox, RadioButton, etc -- inside the UserControl.
This works great when I just set the UC on a page, bind, and go.
Now, I'm attempting to use this control in the ItemTemplate of a ListView like so;
<ItemTemplate><uc1:MyItem ID="MyItem1" runat="server" DataSource='<%# Container.DataItem %>' /></ItemTemplate>
and bind to an array of those objects. The array is populated but I'm reaching my DataBind method of the UC with DataSource = null. Am I missing something?
EDIT: Holidays kept me away from this.
So, apparently I was calling base.DataBind() too late. My LoadForm(DataSource) method to load the object into the form fields preceded base.DataBind(). Swapping them fixed allowed me access to DataSource with no problem.
public override void DataBind()
{
base.DataBind();
LoadForm(DataSource);
}
Am I understanding my problem right? Was I just doing things out of order?
The "<%# %>" syntax tells the compiler to run the associated code during the control's DataBinding event -- but DataSource needs to be set before the DataBinding event to be effective.
One way to work around the issue might be to do your binding-related processing after the DataBind event runs, such as in PreRender.
You just have to know that you might be reloading the page, and you may try to use the
if(!IsPostBack)
in your Page_Load(object sender, EventArgs e)
Which method is better (performance-wise) if I have DataBoundControl such as GridView, Repeater, and/or DataList and I use the following method to display data:
Eval("ColumnName")
or handling the ItemDataBound or RowDataBound event like:
void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// my code to display data here
}
I prefer the second one for code readability reason, but for performance reason, are they the same (or are they even the same thing)?
I also prefer the second version. It's easier for debugging and separation of html & code in my opinion.
According to this older doc, Improving .NET Application Performance and Scalability, it's more efficient (mentioned on page 297).
Eval might be faster(depends on the situatiuon, because it is also latebound and uses reflection), but via DataBound-Event it is more readable and more future-proof.
I think each are useful in situations. The eval way is a quick and easy way to do something simple if not much logic is needed. But, I've seen it abused by unexperienced programmers.
I recently took over development for a project where they were using a repeater. They were doing something like the following:
<asp:Repeater>
<ItemTemplate>
Field Visible = '<%# (method(dataItem.a)) %>
Field
Field Visible = '<%# method(Eval(dataItem.a),Eval(dataItem.b)) %>'
Field
Field Visible = '<%# (method(dataItem.a)) %>'
Field Visible = '<%# (method(dataItem.b)) %>'
</ItemTemplate>
</asp:Repeater>
This was just painful to look at. It looked like the developers just kept on adding more fields and calling the same method to check if the field should show or not. Something like this could easily be handled in the ItemDataBound and is way easier to upkeep. And you should always program with the expectation that your code will need to be modified/added on to later.
Does anybody know if it is the way to set control's child attributes properties by inline code? I mean something like that
<asp:MenuItem Text="text" NavigateUrl='<%# GetItemURL("val") %>' ></asp:MenuItem>
CodeBehind
protected string GetItemURL(string tag)
{
if (string.IsNullOrEmpty(_pageUrl))
_pageUrl = UrlManager.CastQueryString(Request.Url.ToString());
return string.Format("{0}?item={1}", _pageUrl, tag);
}
Neither of approaches work, whatever you use <%#, <%= , Page.DataBind() etc, you get an obstacle.
It would be very ugly to set such properties in code-behind.
I hope the some method allowing to set such properties in code render blocks is available
thanks in advance.
Your binding syntax is correct. You just need to make sure something is binding the parent of the <asp:MenuItem> control. You can even just run this.Page.Databind(); if there isn't a good databinding context already.
I have a custom server control with a property of Title. When using the control, I'd like to set the value of the title in the aspx page like so:
<cc1:customControl runat="server" Title='<%= PagePropertyValue%>' >
more content
</cc1:customControl>
When I do this, however, I am getting the exact String <%= PagePropertyValue%> being displayed rather than the Property Value that I would like to see.
So after trying the databinding expression (as suggested below). I don't get the string literal that looked bad but I don't get anything else either.
<cc1:customControl runat="server" Title='<%# PagePropertyValue%>' >
more content
</cc1:customControl>
What do I need to do to my custom control to take this sort of value? Or is there something I need to do to the page.
You cant. <%= %> will write the string directly to the response-stream, which happens after the server control is constructed. See this post for an explanation.
So its either codebehind, or <%# + databinding as Zachary suggests.
As a followup to my own question, I have discovered that what I really wanted was to use ASP.NET Expressions using the <%$ syntax, since what I wanted to do was put in localized content.
This can be done with apparently no extra handling on the server control side.
<cc1:customControl runat="server" Title='<%$ Resouces: ResourceFile, ContentKey %>' >
more content and controls
</cc1:customControl>
This works just fine.
Try using databinding syntax:
<%# PagePropertyValue %>
For the bind property value to work correctly as suggested, you will have this in the aspx or ascx file :
<cc1:customControl runat="server" Title='<%# PagePropertyValue %>' >
more content
</cc1:customControl>
You will then need to actually bind data in your page wich you have to add this in you code behind file (code in C#)
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}
That way it will bind the data in your ascx or aspx file.
Note that this is specific to control attributes. When using the <%= syntax outside control attributes meaning anywhere else in the page the syntax works as expected. So this
<%=GetCapitalUserName()%>
would call the correct method and inject the result of the call in the page.