How to use Eval in codebehind to set Page.Title - asp.net

I have a SQLDataSource that is bound to a ListView control but I want to place parts of the bound record into the HTML TITLE attribute. Here is my codebehind file that I want to change so it can use Eval to construct a dynamic TITLE based on the data content:
Public Partial Class zShowAd
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.Page.Title = " Dynamically set in ASPX page"
'how to use Eval here instead of the above constant ??
End Sub
End Class
Here is the corresponding .aspx file:
<%# Page Language="vb" AutoEventWireup="false" MasterPageFile="~/zSEO.master"
CodeBehind="zShowAd.aspx.vb" Inherits="Zipeee.zShowAd" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div>
<asp:ListView ID="ShowAd" runat="server" DataSourceID="aPosting">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</LayoutTemplate>
<ItemTemplate>
<div>
<div id="wrapper">
<div id="header"></div>
<div id="main">
<div id="nav"> AdID: <%#Eval("AdID")%></div>
<div id="extras">Price: <%#Eval("Price")%></div>
<div id="content"> <%#Eval("AdDesc")%></div>
</div>
<div id="footer"></div>
</div>
</div>
</ItemTemplate>
</asp:ListView>
<asp:sqldatasource runat="server" id="aPosting"
ConnectionString="<%$ ConnectionStrings:ZIPeeeConnectionString2 %>"
SelectCommand="spGetAdByID" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:QueryStringParameter Name="AdId" QueryStringField="a" Type="String" />
</SelectParameters>
</asp:sqldatasource>
</div>
</asp:Content>

You can call a method (Sub) of the page's code behind by putting the following somewhere inside the ItemTemplate of your ListView:
<%# SetPageTitle(Eval("SomeProperty")) %>
Then in your code behind (sorry it's in C#):
protected void SetPageTitle(object title)
{
this.Title = title.ToString();
}
Alternatively, you can also pass the complete data item, instead of just one property:
<%# SetPageTitle(Container.DataItem) %>
Update (to answer your comment):
<%# ... %> is a so-called data-binding expression. It only works inside of a data-bound control (the ListView in your example) and it always works with the current record (typically you display more than one record in a data-bound control like the ListView).
So when you use <%# Eval("Price") %>, you are displaying the value of the current record's "Price" column. If your query, would return more than one record, then this would be executed for each record, and when setting the page title (as shown above), the page's title would be the value from the last record.
On the other hand <%= ... %>, is just a normal server-side code snippet (don't know if there is a specific name for it), which does not know about the data-binding context (e.g. which is the current record).
Please see the following question for more details: When should I use # and = in ASP.NET controls?

Related

How to databind a local variable in an ASPX template?

I have a UserControl named SlidingScaleTableReadonly with a bindable public member ScaleEntries, which take a List of struct instances. In the parent page, these lists are stored in a dictionary (InsulinSlidingScaleProtocolEntries), and I must render one SlidingScaleTableReadonly for each entry in this dictionary. Here's my template code so far:
<%# Register TagPrefix="uc" TagName="SlidingScaleTableReadonly" Src="~/Patient/SlidingScaleTableReadonly.ascx" %>
<asp:Content ContentPlaceHolderID="phContent" runat="server">
<h1>Échelles</h1>
<% For Each drug In InsulinSlidingScaleProtocolEntries %>
<h2><%= drug.Key %></h2>
<uc:SlidingScaleTableReadonly runat="server" ScaleEntries="<%# drug.Value %>" />
<% Next %>
</asp:Content>
My problem is at line 7:
BC30451 'drug' is not declared. It may be inaccessible due to its protection level.
If I replace drug.Value with a property available in code behind, the new variable can be found. I'm guessing it's not possible to directly data-bind local variables in ASPX? If that's the case, how can I use data-binding inside an iteration?
Edit - Changing the provenance of the bound value
I've changed the code a bit. Right after the "For Each" loop opening, a code-behind property named CurrentDrug is reassigned with the value of drug.Value, and uc:SlidingScaleTableReadonly get it's ScaleEntry from that new property. But that doesn't work either, the reassignment won't do shuck and ScaleEntry is always Nothing (or whatever initial value I gave to CurrentDrug).
Here's the new template:
<%# Register TagPrefix="uc" TagName="SlidingScaleTableReadonly" Src="~/Patient/SlidingScaleTableReadonly.ascx" %>
<asp:Content ContentPlaceHolderID="phContent" runat="server">
<h1>Échelles</h1>
<% For Each drug In InsulinSlidingScaleProtocolEntries
CurrentDrug = drug.Value %>
<h2><%= drug.Key %></h2>
<uc:SlidingScaleTableReadonly runat="server" ScaleEntries="<%# CurrentDrug %>" />
<% Next %>
</asp:Content>
And code-behind:
Public CurrentDrug As List(Of ScaleEntry)
Public Property InsulinSlidingScaleProtocolEntries As Dictionary(Of String, List(Of ScaleEntry))
'...
End Property
Edit - (Not) a solution: Stopped using aspx templates
I have to move on, and it seems like I'm not going to do any progress with aspx templates. I've rewritten the page so the UserControl is declared and inserted in code-behind. I think that's not how one should build an interface, that's not where that kind of logic should be place but I really want to move on.
Here's the new template code:
<asp:Content ContentPlaceHolderID="phContent" runat="server">
<h1>Échelles</h1>
<div id="scaleContainer" runat="server"></div>
</asp:Content>
Code-behind:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
For Each prescription In InsulinSlidingScaleProtocolEntries
Dim label As New HtmlGenericControl("h2") With {
.InnerText = prescription.Key
}
Dim table = CType(Page.LoadControl("~/Patient/SlidingScaleTableReadonly.ascx"), SlidingScaleTableReadonly)
table.ScaleEntries = prescription.Value
scaleContainer.Controls.Add(label)
scaleContainer.Controls.Add(table)
Next
End Sub
If you have a better solution, I'll be happy to see it.

Show/hide HTML table row in include file

I have a page (Default.aspx) that uses an include file to display left navigation bar content.
<asp:Content ID="Content4" ContentPlaceHolderID="ContentPlaceHolder_leftnav" Runat="Server">
<!--#include file="../../includes/menus/left_nav/menu.htm" -->
</asp:Content>
In menu.htm, I have an HTML table. There is one menu item (table row) that I want to display for only certain users, so I have it set to display:none;.
In the codebehind of Default.aspx, if the user is in the list of allowed users, I want to change the display attribute of that table row, but I can't figure out how to access it. Any ideas? Is there a better way to do it?
Thanks in advance.
A quick way to refactor this may be to convert the menu into a user control that contains a Table control that is easy to manipulate:
<%# Register TagPrefix="uc" TagName="Menu" Src="~/Menu.ascx" %>
<asp:Content runat="server" ID="Content4" ContentPlaceHolderID="ContentPlaceHolder_leftnav">
<uc:Menu runat="server" id="ucMenu" />
</asp:Content>
Menu.ascx replaces menu.htm and would look something like this:
<asp:Table ID="tblMenu" runat="server">
<asp:TableRow ID="trSecured" runat="server">
<asp:TableCell ID="tdSecured">Secured (Make Hyperlink)</asp:TableCell>
</asp:TableRow>
<asp:TableRow ID="trNonSecured1">
<asp:TableCell ID="tdNonSecured">Non-Secured (Make Hyperlink)</asp:TableCell>
</asp:TableRow>
</asp:Table>
Then in your Menu.ascx User Control you can handle the menu display logic:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'CanViewSecuredPage should be in it's own class so you can share it between menu display
'logic and for securing the actual page itself (in case they navigate directly by URL).
If Not CanViewSecuredPage() Then
Dim tblTable As Table = CType(Me.FindControl("tblMenu"), Table)
'Or do .FindControl to not be bound to ordinal.
tblTable.Rows(0).Visible = False
End If
End Sub

asp.net output from a SOAP page location using response.write

I hope someone can help. I created a webservice and it returns XML via SOAP fine and well. It transforms fine with XSLT and I return the HTML to a ASP VB.net webform.
I call the functions in the code behind with a button.
Everything works great except the transformed output always ends up at top of the page. I return the result to a label, put the label in a different contentplaceholder but it always is on top. I want the input items(text box) and button to float at the top.
Here is the very simple main webform - plus a bit from where the results are coming from.
<%# Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/Site.Master" CodeBehind="WebForm1.aspx.vb" Inherits="WS_NewCar.WebForm1" %>
<asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<p>
<img src="images/barner.jpg" style="width: 508px; height: 198px; margin-left: 280px" /></p>
<p>
</p>
<p>
<asp:TextBox ID="txtInput" runat="server"></asp:TextBox>
</p>
<p>
</p>
<p>
</p>
<p>
<br />
Click here for SOAP request. <asp:Button ID="btnConvert" runat="server" Text="Search" />
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<asp:Label ID="lblMake" runat="server" Text="Please enter vehicle make"></asp:Label>
</asp:Content>
Dim sr As New StreamReader(memoryStream)
response.Write(sr.ReadToEnd())
sr.Close()
End Function
Protected Sub btnConvert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConvert.Click
lblMake.Text = callWS(txtInput.Text)
End Sub
Response.Write(sr.ReadToEnd()) will always render at the top of the page. It is called before the page is rendered. Try changing it by adding a label where you want the output to appear and do the following in your page_load
label1.Text = sr.ReadToEnd()

Intellisense not showing up for some controls in code behind

i'm kind of an asp.net beginner and i'm trying just to set the visible attribute dynamically but i can't access "TestLinkBox" nor the "TestLink" id in the code behind. Ive tried to rebuild the solution, to delete the designer.cs file and let it be recreated and tried a few solutions I found on stackOverflow as you can see in the code behind but i always get the "Object reference not set to an instance of an object." error. What am I doing wrong?
PART OF THE ASP.NET CODE
<%# Page Title="" Language="C#" MasterPageFile="~/Public/Main.Master"
AutoEventWireup="true" CodeBehind="SpecifikacijaDetails.aspx.cs" Inherits="web.Public.SpecifikacijaDetails"
%>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server"></asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<mc:VijestiTraka ID="vijestitraka" runat="server"></mc:VijestiTraka>
<div class="middle_content_box">
<asp:ListView ID="ListView1" runat="server" DataKeyNames="SpecifikacijaID"
DataSourceID="SqlDataSource1">
<AlternatingItemTemplate>
<div class="details_title_box">
<p class="title"><strong><%# Eval("Brand") %></strong>
<%# Eval( "Model") %>
</p>
</div>
<div class="left_column">
<div class="pregled_modela_slika margb30">
<img src='<%# Eval("SlikaMobitela") %>' />
</div>
<div id="TestLinkBox" class="testLink" runat="server" visible="false">
<asp:HyperLink runat="server" ID="TestLink" NavigateUrl='<%#"~/Public/TestSpecifikacije.aspx?SpecifikacijaID=" + Eval("SpecifikacijaID")%>'
Text="Pogledajte kompletan test"></asp:HyperLink>
</div>
CODE BEHIND
using (MobBL temp = new MobBL())
{
if (temp.ProvjeriImalTest(Int32.Parse(Request.QueryString["SpecifikacijaID"])) > 0)
{
//ListView1.FindControl("link_za_test").Visible = true;
//HtmlControl htmlDivControl = (HtmlControl)Page.FindControl("link_za_tet");
//htmlDivControl.Visible = true;
}
}
The controls your are trying to access in code behind are inside an item template. For this reason, you cannot access them via intellisense because they are not actually on the form - they will be added when the parent control (ListView1) is bound.
Subscribe the the item databound event of the listview control. In there, you can access the child controls for each item in the listview. Something like this would get you the control:
e.Item.FindControl("TestLinkBox");

How to make UpdatePanel inside ListView work?

I have a page with a listview that shows something like posts. On each post there should be a "rate box" which works similar to the "Like" button in facebook. The rate box is a User Control, that has an update panel inside it.
If I put the control with some random values in the page it works great - but when I put it inside the ListView, where it should be located, it won't work. The method is being called, but nothing happens.
I simplified the code a bit to make it easier to understand:
The "rate box" control:
protected void OnRateClick(object sender, ImageClickEventArgs e)
{
Rate++;
RateAmountLiteral.Text = Rate.ToString();
RateButton.Visible = false;
FeedbackLiteral.Visible = true;
rateButtonPanel.Update();
}
ascx:
<div class="rate_div">
<asp:UpdatePanel ID="rateButtonPanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<fieldset>
Rate:
<asp:Literal ID="RateAmountLiteral" runat="server"></asp:Literal>
<asp:ImageButton ID="RateButton" runat="server" ImageUrl="icn_rate.png"
OnClick="OnRateClick" />
<asp:Literal ID="FeedbackLiteral" runat="server" Visible="false">Thanks for rating!</asp:Literal>
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
</div>
aspx (using the control):
<asp:ListView ID="PostsView" runat="server" ItemPlaceholderID="itemPlaceHolder2"
<LayoutTemplate>
<div class="posts_div">
<asp:PlaceHolder ID="itemPlaceHolder2" runat="server" />
</div>
</LayoutTemplate>
<ItemTemplate>
<div class="post_div">
<div class="post_body">
<%# CurrentPost.Body %>
</div>
<UC:RatingBox id="RatingBox" runat="server"
PostID="<%# CurrentPost.ID %>"
Rate="<%# CurrentPost.Rate %>"/>
By: <a href="<%# CurrentPost.Author.LinkToProfile %>">
<%# CurrentPost.Author.DisplayName %>
</a> |
<%# CurrentPost.LiteralTime %>
</div>
</ItemTemplate>
</asp:ListView>
While debugging I noticed the controls in the method "OnRateClick" are empty and don't contain the right values. Please advice.
Also if you have any comments about the way I did things, don't hold yourself.
Thanks
There are a lot things that you may not have set up, I cannot tell from just the code snippet you have given. But make sure you do the following: -
1) Place a ScriptManager "" on the page.
If you are using master page in your application and your web page uses the master page, place script manager in master page. Or alternatively,you can also place script manager on specific web pages anyway.
2) Add a Triggers for the button RateButton in your Update panel.

Resources