Which data control would be apt for the scenario? - asp.net

Guys i have a job to display the list of subscribers as it is given in the image. I would like to know which data control in ASP.NET would be perfect for this scenario. I am just playing with Listview but i would like get inputs from the folks here. Thank You. Faraaz.
Update1: Should i use list of gridviews (nested inside a listview) here? Or can it be done with a single list view?

Obviously, grid-view would give you desired tabular layout (probably with the minimal efforts with Auto Generated Columns).
However, if paging, sorting, editing are note required then I would rather user Repeater control. The main reason being precise control over the mark-up. For example, grid-view does not support elements such as <colgroup> or <thead> (again, these elements may not be needed for your layout). If paging/sorting/editing etc is needed then ListView is better choice.
As far as, showing multiple tables goes, you can use nested controls - for example, repeater/list-view nesting a grid-view.
EDIT:
You are not very clear about the structure of data that you have and also about the exact layout that you want. So here's what I am assuming - you have a single List<Subscriber> containing both root subscribers and their children. And in the layout, you want one table for root subscribers followed by multiple tables - one for each root subscriber's children.
Mark-up will be something like
<asp:Repeater runat="server" ID="Outer" >
<HeaderTemplate>
<%-- Put a grid here for parent -->
<asp:GridView runat="server" ID="Root" DataSource='<%# GetRootSubscribers() %>' >
... column def etc
</asp:GridView>
</HeaderTemplate>
<ItemTemplate>
<!-- Put a grid here for children for current root subsriber -->
<asp:GridView runat="server" ID="Child" DataSource='<%# GetChildSubscribers(Eval("MemberID")) %>' >
... column def etc
</asp:GridView>
</ItemTemplate>
</asp:Repeater>
This will be supported by two code-behind methods such as
protected IEnumerable<Subscriber> GetRootSubscribers()
{
// I am not sure how you decide if a subscriber is a parent or not, I have just
// illustrated a condition where you have a parent id field to indicate the same
return allSubscribers.Where(s => s.ParentID == null);
}
protected IEnumerable<Subscriber> GetChildSubscribers(object memberId)
{
// I am not sure how you decide a child subscriber, I have just
// illustrated a condition where you have a parent id field to indicate the same
return allSubscribers.Where(s => s.ParentID.Equals(memberId));
}
// bind the outer repeater to root list
Outer.DataSource = GetRootSubscribers();
Outer.DataBind();
Hope this will give you some idea about how to proceed.

to me this is a GridView with usual header texts. The first bar above you can make with any other control or pure HTML right before the grid. ListViews are not grids and in my opinion should not be used when the final expected result is closer to a grid

Related

Container id structure on controls added to placeholder in repeater

Just ran across a weird thing. We have a page with items rendered in a Repeater. The items in the list have one panel for display and a PlaceHolder for edit mode where controls are added in the item data binding.
We have some client side code working with the fields that got added, and the code was expecting the ids to follow the same container structure you usually see, but for some reason, one level is getting skipped and I don't know why.
With the template below, you'd have the outer panel with an id like ...Repeater_ctl46_ctl100_Display. The PlaceHolder itself doesn't render, nor get included in the id structure in the html, but the id of a HiddenField added to the EditPlaceHolder ends up like ...Repeater_ctl46_ctl100_valueHidden.
The _Display level just doesn't appear. This threw off our client side script because it was expecting the outer panel container to be reflected in all the child controls in the edit template, and it was using that to look them up.
Anyone know why the containing Panel wouldn't be in the id hierarchy?
<ItemTemplate>
...
<asp:Panel ID="Display" runat="server">
<asp:Panel ID="ViewPanel" runat="server"><asp:Label ID="ValueLabel" runat="server" /></asp:Panel>
<asp:PlaceHolder ID="EditPlaceHolder" runat="server" />
</asp:Panel>
<asp:Panel ID="ModButtons" runat="server"><asp:LinkButton ID="EditButton" Text="<%$ Resources:Messages,Edit %>" runat="server" /></asp:Panel>
...
</ItemTemplate>
Okay, after a lot of digging, asp:Panel does not implement INamingContainer, which is why the Panel is not participating in the id naming conventions.
INamingContainer is just a marker interface; it has no properties or methods associated.
So if you want a Panel that can participate in naming conventions, you can make a little derivation and use that instead:
public class NamingPanel : Panel, INamingContainer
{...}

bootstrap metismenu populated by datasource in asp.net

I want to create a "Tree" structured menu that is generated by a datasource.
I know how to do that with an asp.net tree view or a gridview.
However recently I have grown to love bootstrap and I just love the bootstrap mantis menu.
However metismenu only seem to work on lists 'li'. Then this became a problem for me as the list I want to generate is not static is dynamic. So I can't really bind the value one by one I need to have some other way of doing this.
Can anyone give me some ideas on how to achieve this in asp.net webforms?
PS: would a repeater work for this scenario?
You could use a repeater or a listview or pretty much anything that gives you control of the output html...
You have not presented a massive amount of information to go on but I suspect that you have at least some data that contains a text value and a URL.
private void BindMenuData()
{
var menuData = DataLayer.GetMenuStructure();
rptMenu.DataSource = menuData;
rptMenu.DataBind();
}
Then in your HTML/ASPX you will have something like
<asp:Repeater id="rptMenu" runat="Server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<a href='<# Eval("URL")>'><# Eval("LinkText")></a>
</li>
</ItemTempate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
If you then needed sub menus you would need to nest another repeater inside the item template and bind to it in the repeater itemDataBinding/Databound (Cant remember which) event.
The sub menus leads to an extra layer of complexity which could quite easily descend into a mess of spaghetti code so take some time to think it through!
Of course the fall back could always be a method which uses a string builder to generate the HTML for the menu and spit it out to literal.... Not the best option in my opinion though!

Displaying gridview with 3 columns

I have a gallery which holds a large number of thumbnail images and I want to show 6 at a time.
I have this working using the code below, but I can not get the images to display as 2 rows of 3 - it shows as 6 rows of 1.
I can get the desired result by using a datalist but that stops the pageindex function from working.
I'm sure there's an easy solution but I can't figure it out.
<asp:GridView id="GridView1" runat="server" AutoGenerateColumns="False" AllowPaging="True" PageSize="6" onpageindexchanging="PageIndexChanged" PagerSettings-Mode="NextPrevious" PagerSettings-NextPageText="Next" PagerSettings-PreviousPageText="Previous">
<Columns>
<asp:TemplateField>
<itemtemplate>
<asp:Image ID="Image2" runat="server" ImageUrl='<%# Eval("userID", "/imageUpload/Handler.ashx?userID={0}&image=2")%>' ></asp:Image>
</itemtemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You want to use a ListView.. Look at MSDN here: http://msdn.microsoft.com/en-us/library/bb398790.aspx
Most particularly the GROUPING option.
You might want to consider using a simple asp.net repeater control, and render your items as DIVs. You can use CSS "float" directive to cause your DIVs to automatically "wrap" within their container, to efficiently fit the space (very similar to the way text "wraps" within a text box when it reaches the end of the line).
Because they wrap dynamically, float'd DIVs can be a little more user-friendly: if your user has a wide high-resolution screen, maybe the images render as a 1x6 row. If your user shrinks their browser window, the DIVs will automatically re-arrange themselves into a 3x2 grid.
You wouldn't get data-paging behavior for free, but it's not difficult to implement on its own.
You'd probably be happier with a different control (repeater, etc.)... Gridviews are limited in that they match your datasource row-for-row.
If you have to do this in a gridview for some reason, one option would be to modify the SELECT in your data source so that it put your images into 3 columns. You might be able to do that with a pivot and rownumber() function, or other ways. Once you did that, you'd modify your grideview (copy your template column two more times).

ASP.NET Repeat Dynamic Data Main Menu Horizontally?

The default ASP.NET Dynamic Data template by default uses a GridView to display the menu repeating vertically. This doesn't look particularly well. I'm wondering if there is either (a) a way to get the gridview repeating horizontally or (b) use another control that allows horizontal repeating.
A DataList can be used :)
You set an ItemTemplate to specify how the items should be displayed and set the RepeatDirection to Horizontal, bind it to your Dynamic data source and you are done :D
Additionally you can specify the number of columns to be repeated through the RepeatColumns attribute.
This page (scroll down towards the end) has got some examples on how to use a DataList
http://msdn.microsoft.com/en-us/library/7efxhktc.aspx
This is a simple process. In our code-behind file we have to wire up our Dynamic Data connection like so:
Menu1.DataSource = visibleTables
Menu1.DataBind()
Then we create a DataList like so:
<asp:DataList ID="Menu1" runat="server"
CellPadding="3" GridLines="Vertical"
HorizontalAlign="Center" CssClass="DDGridView" RepeatDirection="Horizontal"
ItemStyle-CssClass="td" HeaderStyle-CssClass="th" >
<ItemTemplate>
<asp:DynamicHyperLink ID="HyperLink1" runat="server"><%# Eval("DisplayName")%></asp:DynamicHyperLink>
</ItemTemplate>
</asp:DataList>
You can see that I've utilized (temporarily) the css classes from the default gridview to provide uniform layout/display elements.

Custom SharePoint Navigation 2 Levels Deep

I have a simple site consisting of a root site with 2 child sites.
Now I want the navigation for all 3 sites to be exactly the same and read:
Root Site | Child Site 1 | Child Site 2
With the currently selected site highlighted.
I have been able to nearly do this manually using an asp:repeater control and portalsitemapprovider. The problem is I can either get just the Root Site on the navigation (set ShowStartingNode to True) or just the child sites, I can't get both.
I know you can get both if you use a sharepoint:aspmenu control and set staticdisplaylevels to 2 but I don't like the messy code this control spits out. Basically i want to emulate this controls behaviour wrapped in my own compliant css. Any ideas?
Also as an addition does anyone have any ideas on how I can have it so if subsite1/2 have subsequent subsites/pages, it doesn't matter how many levels deep in the hierarchy a user is navigating, it still highlights the relevant subsite1 or subsite2? My current method compares currentnode with each of the providers nodes to work out which should be highlighted, but this doesn't work once the user has navigated away from the landing page of each subsite.
Thanks!
I think you have to start at the root and render that node in a first repeater and then use the childnodes of the root as a datasource for a second repeater, something like:
<asp:Repeater runat="server" ID="MenuRepeater"
DataSourceID="MainNavigationDataSource">
<HeaderTemplate>
// code here
</HeaderTemplate>
<ItemTemplate>
// code here
<asp:Repeater runat="server" ID="ChildMenuRepeater"
DataSource='<%# ((SiteMapNode)Container.DataItem).ChildNodes %>'>
<HeaderTemplate>
// code here
</HeaderTemplate>
<ItemTemplate>
// code here
</ItemTemplate>
</ItemTemplate>
For your second question, I think (if I understand it correctly) that you could use SiteMapNode.IsDescendantOf() method but I somehow recall that that will not work in SharePoint so I have used this sort of code to check if a node is the "active" node:
string CurrentContextUrl = SPUtility.GetPageUrlPath(HttpContext.Current);
Uri CurrentUri = new Uri(CurrentContextUrl);
bool Active = CurrentUri.LocalPath.Equals(currentNode.Url);
Hope it helps out somehow :-)

Resources