Accessing SiteMapNode Container.DataItem from outside of Parent Repeater - asp.net

I am trying to access the current 'active' top level node from a sitemap repeater from outside of the ASP.NET repeater used to render it, this is for CSS styling purposes as I want to place the child nodes on the subsequent row with different styling horizontally. At present I have the following code which I can't get to display correctly using CSS.
<asp:SiteMapDataSource ID="topNavLevel" runat="server" ShowStartingNode="false" />
<asp:Repeater runat="server" ID="rptParent" DataSourceID="topNavLevel">
<HeaderTemplate><ul id="lawMenu" class="topMenu"></HeaderTemplate>
<ItemTemplate>
<li>
<asp:HyperLink runat="server" ID="parentLink" NavigateUrl='<%# Eval("Url") %>'><span class="t"><%# Eval("Title") %></span><span class="l"></span><span class="r"></span></asp:HyperLink>
<asp:Repeater ID="rptChild" runat="server" DataSource='<%# ((SiteMapNode) Container.DataItem).ChildNodes %>'>
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:HyperLink ID="childLink" runat="server" NavigateUrl='<%# Eval("Url") %>'><span class="t"><%# Eval("Title") %></span><span class="l"></span><span class="r"></span></asp:HyperLink>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</li>
</ItemTemplate>
<FooterTemplate>
</ul></FooterTemplate>
</asp:Repeater>
I would like to display the child nodes on the next light blue element which I can do perfectly well from a seperate div if this was not rendered using a child repeater. In the image below Blog and Services are top level nodes and their subseqent nodes (2 for each) should be displayed on the light-blue row below. Is this possible?

To get the parent repeaters DataItem as if you weren't inside your child repeater:
<%# DataBinder.Eval(((System.Web.UI.WebControls.RepeaterItem)Container.Parent.Parent).DataItem, "Property") %>

I have solved this now. For anyone else coming across this post here's the solution:
<asp:SiteMapDataSource ID="topNavLevel" runat="server" ShowStartingNode="false" />
<asp:Repeater runat="server" ID="rptParent" DataSourceID="topNavLevel">
<HeaderTemplate>
<ul id="lawmenu" class="law-menu">
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:HyperLink runat="server" ID="parentLink" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</div>
<div class="law-nav_nav2">
<asp:SiteMapDataSource ID="secondNavLevel" runat="server" ShowStartingNode="false" StartingNodeOffset="1" />
<asp:Repeater ID="rptChild" runat="server" DataSourceID="secondNavLevel">
<HeaderTemplate>
<ul class="law-menu_nav2"style="z-index:100">
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:HyperLink ID="childLink" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</div>
The HeaderTemplate takes care of the list container styling then the repeater items are listed out one at a time with an offset of 1 for the current node. This looks easy based on what I have seen around the net, I'm just fairly new to some elements of ASP.NET :) Thanks.

Related

how to group the layouttemplate in listview

I know the way to group the item . but how to group the layouttemplate each 8 databound items ?
here is the code
<ul class="slides">
<asp:ListView runat="server" ID="MyListView" OnItemDataBound="MyListView_ItemDataBound" GroupItemCount="2" >
<LayoutTemplate>
<li>
<asp:PlaceHolder runat="server" ID="groupPlaceHolder" />
</li>
</LayoutTemplate>
<GroupTemplate>
<div class="gourptpl">
<asp:PlaceHolder runat="server" ID="itemPlaceHolder"/>
</div>
</GroupTemplate>
<GroupSeparatorTemplate>
<div class="sper"></div>
</GroupSeparatorTemplate>
<ItemTemplate>
<%-- The item template is used to render each of the rows of the DataTable that has been binded to the ListView control. --%>
<div class="ft-item">
<span class="ft-image">
<asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click">
<asp:Label runat="server" ID="ButtonText" />
<asp:Image ID="Image1" runat="server" />
</asp:LinkButton>
</span>
</div>
</ItemTemplate>
</asp:ListView>
</ul>
All i want is to repeat the GroupTemplate each 2 items and the LayoutTemplate each 8 items .
Thanks .
I helped myself . nest another listivew in the itemtemplate of the listview above . Actually i wanna customize the listview class but dun know how .

How to find control bounded in item template on master page from content page?

I am having a nested repeater on the master page. And a hiddenfield in its item template.
i want the value of hiddenfield on content page.Like this
<ul class="categories">
<li>
<div id='cssmenu'>
<h4>Categories</h4>
<asp:Repeater ID="repcategory" runat="server" OnItemDataBound="repcategory_ItemDataBound">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<asp:HiddenField ID="hf1" Value='<%# Eval("CategoryID") %>' runat="server" />
<li class="active has-sub">
<a href='#'><span>
<%#Eval("CategoryName") %></span></a>
<asp:Repeater ID="repsubcategory" OnItemDataBound="repsubcategory_ItemDataBound" runat="server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<asp:HiddenField ID="hf2" Value='<%# Eval("SubCategoryID") %>' runat="server" />
<li class="has-sub">
<a href='#'><span>
<%#Eval("SubCategoryName") %></span></a>
<asp:Repeater ID="repsubcategory2" runat="server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<asp:HiddenField ID="hf3" Value='<%# Eval("SubCategory2ID") %>' runat="server" />
<li>
<a href="ClientProductSubCategory2.aspx"><span>
<%#Eval("SubCategory2Name") %></span></a>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</li>
</ItemTemplate>
<FooterTemplate></ul></FooterTemplate>
</asp:Repeater>
</li>
</ItemTemplate>
<FooterTemplate></ul></FooterTemplate>
</asp:Repeater>
</div>
I want the value of subcategory2id on the content page and codded like this.
HiddenField hiddensubcategory2id = (HiddenField)Master.FindControl("hf3");
DataSet ds = new ClientProductView().GetAllProductSubCategory2(hiddensubcategory2id.Value);
repContent.DataSource = ds;
repContent.DataBind();
But this is returning a null value. Please help me to solve this problem
Try finding the control within the repeater object itself, like this:
var hiddensubcategory2id = repsubcategory2.FindControl("hf3") as HiddenField;
Note: You should always check to see if the result of a FindControl() is null or not, like this:
if(hiddensubcategory2id != null)
{
// Do something with the control you found
}

Find div in repeater, and change it's style element

I have a repeater object that looks like the following
<asp:Repeater id="rptSpecialNotes" runat="server">
<headerTemplate><ol type="A"></HeaderTemplate>
<itemtemplate>
<li>
</li>
<asp:UpdatePanel ID="udpSpecialNotesRepeater" runat="server" UpdateMode="Always">
<ContentTemplate>
<div id="specialNotes" name='<%# Eval("itemId") %>' runat="server">
<asp:imagebutton runat="server" width="20" class="floatLeft" id="specialNotesItem" imageurl='<%# Eval("ImageUrl") %>' commandname="specialNotesImageChange" commandargument='<%# Eval("itemId") %>'></asp:imagebutton>
<span class="subject"><p><%# eval("Subject") %></p></span>
<br /><br />
<p><%# Eval("AgendaNote")%></p>
<br />
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID ="followAlongControl" EventName ="Tick" />
</Triggers>
</asp:UpdatePanel>
<asp:Repeater id="specialNotesAttachmentsRepeater" OnItemCommand="specialNotesAttachmentRepeater_ItemCommand" runat="server" datasource='<%# Container.DataItem.Row.GetChildRows("attachmentRelation") %>' >
<itemtemplate>
<br />
<a href='<%# Container.DataItem("attachmentPath") %>'><%# Container.DataItem("attachmentName") %></a>
</itemtemplate>
</asp:Repeater>
</itemtemplate>
<footerTemplate></ol></FooterTemplate>
</asp:Repeater>
I want to change the background color of the div 'specialNotes' depending on the imageurl of the image button. So if it's checked, the div would be grey, if not, then i'd leave it blank.
Is there a way to do this in the code-behind with VB?
You don't have to "Find" the div after the page has loaded, you can do this as it is getting bound. I imagine that when you say "if it's checked" that you refer to the imagebutton acting as a checkbox, and you want to change the color depending on the location(path) of the image. So I would this in the div:
<div style='<%# doColor(Eval("ImageUrl")) %>'>
Content in the div
</div>
and then this in the code behind:
Public Function doColor(img As Object) As String
If img.ToString() = "MyPath" Then
Return "background-color:red"
Else
Return "background-color:green"
End If
End Function
that way if the ImageUrl equals "MyPath" the background of your div will be red, otherwise it will be green.
Add a runat="server" to your div tag. Then your code behind, you can access that div using:
udpSpecialNotesRepeater.FindControl("div")
on your DataBound event.
It is alot easier to do it in jQuery though. You can just grab id of the div $("#specialNotes") and use the .attr function to change its background.
can use:
Control divControl=e.Item.FindControl("divControl");

ASP.NET C#, Access div element from nested Listview Code Behind

I'm trying to get the (div id="imgGallery" runat="server") element from nested Listview to modify the class name programatically.
<asp:ListView ID="ListView1" runat="server" ItemPlaceholderID="itemPlaceHolder1" onitemdatabound="ListView1_ItemDataBound">
<ItemTemplate>
<asp:Label ID="VersionId" runat="server" Text='<%# Eval("VersionId") %>' Visible="false" />
<asp:Label ID="MenuContent" runat="server" Text='<%# Eval("ContentText") %>' />
<br />
<asp:ListView ID="ListView2" runat="server" ItemPlaceholderID="itemPlaceHolder2">
<ItemTemplate>
<div id="imgGallery" class="images" runat="server">
<asp:Image ID="Image1" ImageUrl='<%# Eval("ImageUrl") %>' runat="server" ToolTip="Text" />
</div>
</ItemTemplate>
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceHolder2"></asp:PlaceHolder>
</LayoutTemplate>
</asp:ListView>
</ItemTemplate>
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceHolder1"></asp:PlaceHolder>
</LayoutTemplate>
<ItemSeparatorTemplate>
<br />
<hr />
<br />
</ItemSeparatorTemplate>
on my code behind I tried the code below which doesn't work... and I tried different ways but can't find solution.
ListView listView2 = (ListView)ListView1.FindControl("ListView2");
HtmlGenericControl mydiv = (HtmlGenericControl)listView2.FindControl("imgGallery");
mydiv.Attributes.Clear();
You sholuld work with inner element of databound controls on databinding stage or iterating through row collection (called databind method before)

What is the cleanest way to make a dynamic list of buttons in asp.net?

I want to change this list so that it is dynamically populated:
<ul>
<li id="Tab1" class="selected" runat="server">
<asp:LinkButton ID="LinkButton1" OnClick="LinkButton1_Click"runat="server">
Tab1 Text
</asp:LinkButton>
</li>
<li id="Tab2" runat="server">
<asp:LinkButton ID="LinkButton2" OnClick="LinkButton2_Click" runat="server">
Tab2 Text
</asp:LinkButton>
</li>
<li id="Tab3" runat="server">
<asp:LinkButton ID="LinkButton3" OnClick="LinkButton3_Click" runat="server">
Tab3 Text
</asp:LinkButton>
</li>
</ul>
I tried using this code:
<asp:ListView ID="ListView_Tabs" OnItemCommand="ListView_ChangeTab" runat="server">
<LayoutTemplate>
<div class="tabs">
<ul>
<li id="itemPlaceholder" runat="server" />
</ul>
</div>
</LayoutTemplate>
<ItemTemplate>
<li>
<asp:LinkButton Text='<%# Eval("displayName") %>' CommandName='<%# Eval("parameterName") %>' runat="server"/>
</li>
</ItemTemplate>
</asp:ListView>
and populate it in code behind:
ListView_Tabs.DataSource = comeClass.GetTabs();
ListView_Tabs.DataBind();
But I don't see any clear way to set class='selected' to the last link I clicked ( or rather the list item that contains the link )
So my question is
What is the cleanest way to make a dynamic list of buttons in asp.net, or even just in .net?
It doesn't have to be anything like my approach. I'm not even sure using ListView is the best approach to solve this.
You can leverage the SelectedItemTemplate and SelectedIndex attributes of your ListView to accomplish this.
Change the CommandName property to "Select" in your ListItemTemplate. That way when the the postback occurs, the ListView will have the row index of the LinkButton you selected. You can then set your custom command to the CommandArgument paramter for any custom processing when the ItemSelected event is raised by clicking the LinkButton.
Then in your SelectedItemTemplate, you can apply the class right there. Your ListView would look something like this:
<asp:ListView ID="ListView_Tabs" OnItemCommand="ListView_ChangeTab" runat="server">
<LayoutTemplate>
<div class="tabs">
<ul>
<li id="itemPlaceholder" runat="server" />
</ul>
</div>
</LayoutTemplate>
<ItemTemplate>
<li>
<asp:LinkButton Text='<%# Eval("displayName") %>' CommandName="Select" CommandArgument='<%# Eval("parameterName") %>' runat="server"/>
</li>
</ItemTemplate>
<SelectedItemTemplate>
<li>
<asp:LinkButton Text='<%# Eval("displayName") %>' CommandName="Select" CommandArgument='<%# Eval("parameterName") %>' CssClass="selected" runat="server"/>
</li>
</SelectedItemTemplate>
</asp:ListView>
You can use the ItemDataBound event for that and set the selected class there.
You would identify the selected item with the CommandParameter.
Compare the e.DataItem to a property of the item you set as the CommandParameter.
So you would have something like this in the ItemDataBoud:
YourClass item = e.Item.DataItem as YourClass;
if(item == null) return;
if(item.YourKeyProp == e.CommandArgument)
{
Literal classlit = e.Item.FindControl("classLiteral") as Literal;
if(classlit == null) return:
classlit.Text = "Selected";
}
Use a Repeater instead:
<ul>
<asp:Repeater runat="server">
<ItemTemplate>
<li>
<asp:LinkButton runat="server" CommandName='' CommandArgument='' Text='' />
</li>
</ItemTemplate>
</asp:Repeater></ul>

Resources