/// <summary> /// Creates a column header cell (<c>td</c>) that is sortable (the user can click on it to sort /// ascending/descending) /// </summary> /// <typeparam name="T">The type being displayed in the view</typeparam> /// <typeparam name="TProp">The type of the property whose column header is being created</typeparam> /// <param name="html">The <see cref="HtmlHelper{T}"/></param> /// <param name="viewData"> /// The <see cref="PagedSortedViewModel{T}"/> view data from the <see cref="HtmlHelper{T}"/> /// </param> /// <param name="propertySelector"> /// A lambda expression that returns one of the properties on the object /// </param> /// <param name="text">The text to display in the column header cell</param> /// <param name="routeValues"> /// The route values to include in the link that allows sorting. This can be null, which will cause the /// current page's route and URL parameters to be used /// </param> /// <param name="sortRouteValueName"> /// The route value name used to store the sorting settings string in. This can be null which will /// cause the value <c>sort</c> to be used /// </param> /// <param name="htmlAttributes">Html attributes to apply to the <c>th</c> tag</param> /// <returns>The HTML</returns> private static MvcHtmlString SortableColumnHeader <T, TProp>(this HtmlHelper html, PagedSortedViewModel <T> viewData, Expression <Func <T, TProp> > propertySelector, string text, RouteValueDictionary routeValues, string sortRouteValueName, IDictionary <string, object> htmlAttributes) { UrlHelper url = new UrlHelper(html.ViewContext.RequestContext); sortRouteValueName = sortRouteValueName ?? "sort"; routeValues = routeValues ?? url.RouteToCurrentPage(); htmlAttributes = htmlAttributes ?? new Dictionary <string, object>(); Sorter <T> sorter = viewData.Sorter; bool sortDirection; KeyValuePair <LambdaExpression, bool> selectorPair = sorter.OrderedPropertySelectors[0]; bool isFirstSort = sorter.PropertySelectorsEqual(propertySelector, selectorPair.Key); if (isFirstSort) { sortDirection = !selectorPair.Value; } else { sortDirection = true; } bool currentSortDirection = sorter.GetSortDirectionForProperty(propertySelector); RouteValueDictionary routeDictionary = new RouteValueDictionary(routeValues); routeDictionary[sortRouteValueName] = sorter.Clone().SortBy(propertySelector, sortDirection).Encode(); TagBuilder th = new TagBuilder("th"); TagBuilder a = new TagBuilder("a"); string linkTitle = String.Format("{0} (Sorted {1})", text, (currentSortDirection ? "Ascending" : "Descending")); a.MergeAttribute("title", linkTitle); a.MergeAttribute("href", url.RouteUrl(routeDictionary)); th.AddCssClass("Sortable"); if (isFirstSort) { th.AddCssClass("PrimarySortColumn"); } else { th.AddCssClass("NonPrimarySortColumn"); } if (currentSortDirection) { th.AddCssClass("SortedAscending"); } else { th.AddCssClass("SortedDescending"); } a.InnerHtml = text; th.InnerHtml = a.ToString(); th.MergeAttributes(htmlAttributes); return(MvcHtmlString.Create(th.ToString())); }