Can I define Default Sort order in LinQ - asp.net

If I have a nested ListView, and I'm calling a related table in LinQ, how do I sort it, without resorting to the ItemDataBound event of the parent?
Pseudo Code (UPDATED WITH SOLUTION):
<asp:ListView ID="lv" runat="server" OnItemDataBound="lv_ItemDataBound" >
<LayoutTemplate>
<!-- Product Category Stuff -->
<asp:PlaceHolder Id="itemPlaceholder" runat="server"></asp:PlaceHolder>
</LayoutTemplate>
<ItemTemplate>
<asp:ListView ID="lvInner" runat="server" DataSource='<%# <%# ((Category)Container.DataItem).Products.OrderBy(p => p.Description) %> %>'>
<LayoutTemplate>
<ul>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</ul>
</LayoutTemplate>
<ItemTemplate>
<li>Item Stuff</li>
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:ListView>
Perhaps the method is deceptively simple, but I want the inner Products to be sorted by a field. I can't see a way to do it declaratively as LinQ creates this Query on the fly, if I'm not mistaken, and doesn't do sorting.
Any thoughts?
UPDATE
Updated the Example to the following:
<%# ((Category)Container.DataItem).Products.OrderBy(p => p.Description) %>
Hope it helps someone else!

My assumption is that Products is an IEnumerable<Product> (or IQueryable). If that is the case, why not just add the OrderBy method to the evaluation, like so:
<%# Eval("Products.OrderBy(p => p.FieldToSortOn)") %>

Related

How to get the parent item index inside child repeater?

I have nested repeaters like this:
<asp:Repeater ID="rptQuestoes" runat="server">
<HeaderTemplate>
<ol class="orderedList">
</HeaderTemplate>
<ItemTemplate>
<li>
<%#DataBinder.Eval(Container.DataItem, "QuestionName")%>
<asp:Repeater ID="rptAlternativas" DataSource='<%# Container.DataItem.Row.GetChildRows("Questionario") %>' runat="server">
<HeaderTemplate>
<ul style="list-style-type: none">
</HeaderTemplate>
<ItemTemplate>
<li>
<input id="rb" type="radio" name='ITEM_INDEX_HERE' value='<%#Container.DataItem("AlternativeID")%>' /><%#Container.DataItem("AlternativeName")%>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</li>
</ItemTemplate>
<FooterTemplate>
</ol>
</FooterTemplate>
</asp:Repeater>
I want to print the parent item index inside the child repeater (rptAlternativas) in VB right in ITEM_INDEX_HERE marker. How can I achieve this?
I hope someone can give you a better answer than this, but I would consider adding a property to your "Quentionario" sub elements.
<asp:Repeater ID="rptAlternativas"
DataSource='<%# Container.DataItem.Row.GetChildRows("Questionario") %>'
runat="server">
Can you add a question id to each of these objects? You're already binding to their AlternativeId in your radio button, adding a question id to these objects would let you do simply:
<input id="rb" type="radio" name='<%#Container.DataItem("QuestionId")%>' value='<%#Container.DataItem("AlternativeID")%>' />
Even if these objects are auto-generated from an ORM, you should be able to add the property in via a partial class, and then just set the appropriate values in a simple loop.

ASP.NET repeater over list of hyperlinks

I am making a pagination feature, because the default one in webforms uses postbacks, which is pathetic really.
Just wondering if there is a better way to output this List of links.
paginator = new Paginator(10,35);
// List<HyperLink>
rptPagination.DataSource = paginator.getPageLinks();
<asp:Repeater ID="rptPagination" runat="server">
<ItemTemplate>
<%# Eval("Text") %>
</ItemTemplate>
</asp:Repeater>
Obviously if I try to change other properties of the HyperLinks, like target, visible etc this will not be rendered into the page.
You can keep using that syntax and continue with pure HTML:
<ItemTemplate>
<%# Eval("Text") %>
</ItemTemplate>
Or, a server side version:
<ItemTemplate>
<asp:HyperLink runat="server"
NavigateUrl='<%# Eval("NavigateUrl") %>'
Text='<%# Eval("Text") %>' />
</ItemTemplate>

Can't populate update parameters from a ListView's ItemTemplate

I am using a ListView and would like to implement the switch from read only mode to edit mode for a ListView item on the client side. Some of this is discussed at: Inline form editing on client side
I am trying to do this by something like:
<asp:ListView ID="ListViewContactNumber" runat="server">
<LayoutTemplate>
<table cellpadding="0" cellspacing="0">
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<div class="readonly">
<asp:Label ID="LabelType" runat="server"
Text='<%# Server.HtmlEncode(Eval("Name").ToString()) %>'></asp:Label>
Edit
</div>
<div class="edit">
<asp:TextBox ID="TextBoxName" runat="server"
Text='<%# Eval("Name") %>'
MaxLength="256"
Columns="10"></asp:TextBox>
<asp:LinkButton ID="LinkButtonSave" runat="server"
Text="Save"
OnClick="LinkButtonSave_Click"></asp:LinkButton>
Cancel
</div>
</ItemTemplate>
</asp:ListView>
switchState is a Javascript function that simply hides/shows the DIVs with the readonly and edit classnames. In LinkButtonSave_Click I get the value from TexBoxName but it always contains the bound original value and not the edited value that was entered in the texbox.
Does ASP.NET not postback the textbox value because it is in the ItemTemplate or is it something else that's causing this problem?
Could I use a Repeater instead to accomplish this?
when using javascript to change state you must use ajax to update your data ::
It turned out that the ListView was not the source of the problem at all. I was re-databinding on Page_Load without checking if it was a postback.

ASP.NET change a Repeater's DataSource without a postback?

I have a repeater that displays some data from a SQL query:
<asp:Repeater runat="server" ID="damQuickList" OnItemDataBound="damQuickList_OnItemDataBound">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><asp:HyperLink runat="server" ID="damAnchor" /></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
In the codebehind:
damQuickList.DataSource = (Data.RunSelectQuery("SELECT * FROM Table ORDER BY " + radioButton.Value));
damQuickList.DataBind();
Is there a way to change the DataSource and have it update in the Repeater, without having to do a postback in the page (like how AJAX does it)? I've been using the Async controls I found here: http://www.asynccontrols.com/, but there's some issues using them with IE6/7.
Use the ASP.NET AJAX components. Put a ScriptManager on your page, then put a UpdatePanel on your page. Inside the update panels ContentTemplate put your repeater.
A quick example would look something like this...
ASPX Markup
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<table>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<tr>
<td>
<%# Eval("Data") %>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
C# Code Behind
protected void Button1_Click(object sender, EventArgs e)
{
Repeater1.DataSource = yourDataSource;
Repeater1.DataBind();
}
Note the button that 'refreshes' your data source is also inside the content template. Hope it helps.
Off-topic: I hope that's not your real code; I'm pretty sure a malicious user could put anything they wanted into the radioButton.Value field and SQL-Inject you.
Do you mean a full round trip? Can you not put the repeater inside an UpdatePanel?

Can I nest Templates in a Web User Control?

I want to do something like this:
<MyTemplate>
<span><%# Container.Title %></span>
<MySubTemplate>
<span><%# Container.Username %></span>
</MySubTemplate>
</MyTemplate>
Assuming I have a list of Titles that each have a list of Usernames.. If this is a correct approach how can I do this or what is a better way?
If you have a list of titles, that each have their own list of UserNames, it seems like you want to do something with nested repeaters (or other controls), not templates...
<asp:Repeater ID="rptTitle" runat="server" >
<ItemTemplate>
<%# Eval("Title") %>
<asp:Repeater ID="rptUsers" runat="server" >
<ItemTemplate>
<%# Eval("UserName") %>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
And then bind the rptUsers during the ItemDataBound event of rptTitle...
You can do it this way. You can also use:
Labels
Span runat="server" and add them programmatically
(ghetto) string.replace

Resources