StartingNodeUrl - How to programmatically get its value? - asp.net

Is it possible to get the value for StartingNodeUrl programmatically?
My sitemap has 3 levels to it at it's deepest and, depending on what section your are in I want to display all of the children below the parent in a navigation.
I reckon all I have to do is look at where I am in the navigation and put a value in StartingNodeUrl. But I cannot!
Code snippet from MasterPage:
<asp:Repeater ID="Repeater1" DataSourceID="SiteMapDataSource1" runat="server">
<ItemTemplate>
menu items here
</ItemTemplate>
</asp:Repeater>
<asp:SiteMapDataSource ID="SiteMapDataSource1" ShowStartingNode="false" StartingNodeUrl="/about/" runat="server" />
Thanks in advance.
JRenney

To get the StartingNodeUrl programmatically:
string startNodeUrl = SiteMapDataSource1.StartingNodeUrl;
It sounds like you're looking to operate from the current node though, so I imagine that the SiteMapDataSource.StartFromCurrentNode property is more useful for you.

Related

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.

The Controls collection cannot be modified error when using asp Menu control

So here is my problem:
I have a webpage that is using an asp:TreeView control and a sitemap to draw a menu.
<asp:TreeView ID="CatalogTreeViewControl" runat="server" DataSourceID="dsSiteMap">
</asp:TreeView>
<asp:SiteMapDataSource runat="server" ID="dsSiteMap" ShowStartingNode="False" SiteMapProvider="MyXmlSiteMapProvider"/>
This works like a charm, but I want to use the asp:Menu control instead of the TreeView, så I do this:
<asp:TreeView ID="CatalogTreeViewControl" runat="server" DataSourceID="dsSiteMap" Visible="False">
</asp:TreeView>
<asp:Menu ID="Menu1" runat="server" DataSourceID="dsSiteMap"></asp:Menu>
<asp:SiteMapDataSource runat="server" ID="dsSiteMap" ShowStartingNode="False" SiteMapProvider="MyXmlSiteMapProvider"/>
But this results in the following error:
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
What am I doing wrong here?
I got this problem a long time back. I moved my javascript from the head tag to a form tag and it fixed the problem. These links helped me a lot :
"The Controls collection cannot be modified because the control contains code blocks"
http://leedumond.com/blog/the-controls-collection-cannot-be-modified-because-the-control-contains-code-blocks/

How can I prevent duplication of the content in itemtamplate for the alternating template in repeater?

Is there a way to prevent duplication ot an itemtemplate content which will just appear with a different css class for the alternating template block?
<asp:Repeater ID="rptCommentHistory" runat="server">
<ItemTemplate>
<asp:Label ID="lblComment" runat="server" Text='<%#Eval("Comment").ToString() %>'
Class="itemTemplate"/>
</ItemTemplate>
<AlternatingItemTemplate>
<asp:Label ID="lblComment" runat="server" Text='<%#Eval("Comment").ToString() %>'
Class="alternatingTtemTemplate"/>
</AlternatingItemTemplate>
</asp:Repeater>
This should do what you want:-)
<asp:Repeater ID="rptData" runat="server">
<ItemTemplate>
<asp:Label ID="lblData" runat="server" Text='<%# Eval("Comments") %>' CssClass='<%# Container.ItemIndex%2==0?"itemTemplate":"alternatingTtemTemplate" %>'></asp:Label>
</ItemTemplate>
</asp:Repeater>
I never make use of the AlternatingItemTemplate. I don't like having to duplicate my code for the purpose of having an alternating item, and I think that if the code is that different that it cannot be classed as a duplicate, then you shouldn't be using a Repeater control anyway.
Therefore I always just use the ItemTemplate, and make any changes I need to in the ItemDataBound event.
To determine whether the item is a normal, or alternating item, I would do something like:
if ((e.Item.ItemIndex+1 % 2)=0){
//Alternating code here..
}
In your case the only difference is a change to the Label CssClass, so I would do something like:
if ((e.Item.ItemIndex+1 % 2)=0){
Label lblComment = e.Item.FindControl("lblComment");
lblComment.CssClass = "alternatingTtemTemplate";
}
It's not really duplication as such, don't worry about it. You are implementing this pretty much as intended.
The only other option I can think of would be to use the itemtemplate, write some code that is fired on the itemdatabound event and programatically change the css class using FindControl.
I know which I would rather use...
As it seems that the proposed solutions are not satisfying and that there are no other ".net" solution, I would suggest that you do that in javascript (as it doesn't exist in pure CSS).
jQuery allows you to apply a different style on even and odds elements of the selector.
It should work with other elements than table rows...
So something like this should work :
$("#rptCommentHistory span:even").addClass("itemTemplate");
$("#rptCommentHistory span:odd").addClass("alternatingTtemTemplate");
Or you can just set ItemTemplate to all elements and use (it may perform better) :
$("#rptCommentHistory span:odd").removeClass("ItemTemplate").addClass("alternatingTtemTemplate");

Issue with getting a ModalPopUp to display a populated textbox correctly

My site has descriptions of the products we sell and I am currently trying to get those descriptions to pop up inside a modal popupextender. I can get them to popup with a textbox where I have enabled="false" so that it can't be edited, but it shows all the tags along with the text such as the <p>, <li>, etc. Is there a different control I can use inside of my modal that will show my text better?
<!-- Descriptions -->
<asp:TabPanel ID="tab2" runat="server" HeaderText="Descriptions">
<HeaderTemplate>Descriptions</HeaderTemplate>
<ContentTemplate>
<ul class="info">
<asp:ListView ID="lvDescriptions" runat="server" DataSourceID="dsMarketingDescriptions" DataKeyNames="MarketingID">
<ItemTemplate>
<li>
<asp:LinkButton ID="ViewDescriptionButton" runat="server"><%#Eval("MarketingTitle")%></asp:LinkButton>
<asp:ImageButton ID="DeleteDescriptionButton" runat="server" Style="float:right;" AlternateText="" ImageUrl="../../images/delete.png" CommandName="Delete" OnClientClick="return confirm('Are you sure you want to delete this description?')" />
<asp:Panel ID="ViewDescriptionPanel" runat="server">
<asp:ImageButton ID="CancelDescriptionButton" runat="server" ImageUrl="../../images/exit.png" AlternateText="" Style="float:right;"/>
<asp:TextBox ID="Description" runat="server" width="100px" height="100px" Enabled="false" TextMode="MultiLine" Text='<%# Eval("MarketingData") %>'/>
</asp:Panel>
<asp:ModalPopupExtender ID="ViewDescriptionModal" runat="server" BackgroundCssClass="modalBackground" DropShadow="false" DynamicServicePath="" Enabled="true" PopupControlID="ViewDescriptionPanel" TargetControlID="ViewDescriptionButton" CancelControlID="CancelDescriptionButton"></asp:ModalPopupExtender>
</li>
</ItemTemplate>
</asp:ListView>
</ul>
</ContentTemplate>
</asp:TabPanel>
Here's an example of the <%# Eval("MarketingData")%>:
<p>If you are currently trading options on futures or are interested in exploring them further, check out this newly updated trading guide, featuring 25 commonly used options strategies, including butterflies, straddles, strangles, backspreads and conversions. Each strategy includes an illustration demonstrating the effect of time decay on the total option premium involved in the position.</p><p>Options on futures rank among the most versatile risk management tools, and are offered on most CME Group products. Whether you trade options for purposes of hedging or speculating, you can limit your risk to the amount you paid up-front for the option while maintaining your exposure to beneficial price movements.</p>
If the text wont be editable, why don't you use a asp:label instead?
Does the MarketingData field include html tags? Please provide an example of the value for MarketingData.
Edit:
If you know wich tags can be present on your text, you can simply create a property on the class that hold the propoerty called MarketingData, like this:
public string EditedMarketingData
{
get {return MarketingData.Replace("<p>","").Replace("</p>","").Replace("<li>","");}
}
And then change the binding in your text box as:
Text='<%# Eval("EditedMarketingData") %>'
The replacing is kind of ugly, hope you can get that to look better ;)
I think a Literal would be the most appropriate control for this type of content, as it will preserve the HTML in the content. You could probably also use a Label.
If you would prefer to stick with a TextBox though, I would try setting the ReadOnly property to false (instead of Enabled). If you want to achieve the disabled.

Paging for Listview inside a Gridview not working

I have a listview nested inside a gridview.
I'm trying to get paging working on the listview. I thought that it would display the paging controls, and just page through them normally.
It does display the controls, and limits the result set shown to the appropriate number of records (pageSize) but when I click on the paging controls the grid refreshes and nothing changes with the nested listview (it's still on the first page).
I've tried nesting the listview inside an updatepanel, but the behavior remains. The gridview itself is already in an updatepanel.
So this is the layout I've got:
<Gridview ID="gvApplications" DataSourceID="odsApplications" DataKeyNames="ID" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Functions">
<ItemTemplate>
<asp:ListView ID="lvFunctions" runat="server" DataSource='<%#Eval("ApplicationFunctions") %>'
DataKeyNames="ID">
<LayoutTemplate>
<asp:DataPager ID="dpFunctions" runat="server" PageSize="1" PagedControlID="lvFunctions">
<Fields>
<asp:NextPreviousPagerField />
</Fields>
</asp:DataPager>
<ul>
<li>
<span ID="itemPlaceholder" runat="server" />
</li>
</ul>
</LayoutTemplate>
<ItemTemplate>
<asp:Label ID="lblFunction" runat="server" Text='<%# Eval("ApplicationFunction.Name") %>' />
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</Gridview>
Ideas?
Honestly, I would consider using a master-details pattern here. There are a lot of code examples on this. For example:
Google: Master Details Examples with Child Objects
There are also scenarios where the details view (child objects in your case) would display on a separate page. Either way, by displaying the child objects in a separate details view, you avoid the coding and display issues that come with nesting.
Matt Berseth has some of the best code examples out there on this topic:
http://mattberseth.com/blog/gridview/
Listview / datapager combination do not work properly if the listview does not use a datasource control.
Try including a datasource control (objectdatasource could be applicable) in the template field.

Resources