Great answer! But can this be done with two fields?
In my situation, I am creating a Dynamic Data site that keeps records for our crews that go out to ships for equipment repairs. They visit the ship and write up serveral work orders on that visit. So I have a Visits table with a one to many relationship
with a Work Order table (one Visit has many Work Orders). There is a ShipName and a StartDate field in the Visits table. I want to filter the Work Orders list page using a drop down that displays the ShipName and the StartDate sorted first by ShipName and
then by StartDate.
After scouring the web, I came up with the following (in visits metadata):
Yes this works I use it all the time. you cannot sort by two column using the DisplayColumn attribute, I recently created a multi column sort attribute and extension method see below:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class MultiColumnSortAttribute : Attribute
{
private char[] splitChars = new char[] { ',' };
public Dictionary<String, SortDirection> Columns { get; set; }
public MultiColumnSortAttribute(params String[] columns)
{
Columns = columns.ToDictionary(x => x.Split(splitChars)[0], x => x.Split(splitChars)[1].ToEnum<SortDirection>());
}
it's not quite ready for prime time but it will add the sort to your project
public static class QueryExtenderExtensionMethods
{
/// <summary>
/// Sets the initial sort order.
/// </summary>
/// <param name="queryExtender">The query extender.</param>
/// <param name="table">The table.</param>
public static void SetInitialSortOrder(this QueryExtender queryExtender, MetaTable table)
{
var multiColumnSort = table.GetAttribute<MultiColumnSortAttribute>();
if (multiColumnSort != null)
{
var firstEntry = multiColumnSort.Columns.Keys.First();
var order = new OrderByExpression()
{
DataField = firstEntry,
Direction = multiColumnSort.Columns[firstEntry],
};
foreach (var item in multiColumnSort.Columns)
{
if (item.Key != firstEntry)
{
order.ThenByExpressions.Add(new ThenBy()
{
DataField = item.Key,
Direction = item.Value
});
}
}
queryExtender.Expressions.Add(order);
}
else if (table.SortColumn != null)
{
var order = new OrderByExpression()
{
DataField = table.SortColumn.Name,
Direction = table.SortDescending ? SortDirection.Descending : SortDirection.Ascending,
};
queryExtender.Expressions.Add(order);
}
}
}
apply the attribute to you metadata in the same place you use the DisplayColumn attribute
This is something that Microsoft should be addressing anyway. It's not unusual in real world applications to have a drop-down that displays more than one column and for both of these columns to be sorted.
Dynamic Data is a great idea, but it seems to me that Microsoft still hasn't taken it far enough to be practical for production level applications. Maybe that is why it hasn't been fully embraced by the ASP.NET developer community. Hopefully this issue,
along with several other short-comings will be addressed in future releases.
You've been addressing other Dynamic Data issues as well and you shouldn't be doing this all by yourself. This might be hard to believe, but I'm sure that you, like other developers, have a life beyond just writing code! We simply don't have enough time
work our regular jobs and write code for Microsoft in our free time!
sjnaughton
All-Star
27308 Points
5458 Posts
MVP
Re: DisplayFormatAttribute doesn't work when this is a ForeignKey DropDownList / Hyperlink
Jan 16, 2010 02:51 PM|LINK
Sorry about that it was pasting from me [:$]
Dynamic Data
Always seeking an elegant solution.
SonnyTate
Member
24 Points
22 Posts
Re: DisplayFormatAttribute doesn't work when this is a ForeignKey DropDownList / Hyperlink
Dec 12, 2012 07:15 PM|LINK
Great answer! But can this be done with two fields?
In my situation, I am creating a Dynamic Data site that keeps records for our crews that go out to ships for equipment repairs. They visit the ship and write up serveral work orders on that visit. So I have a Visits table with a one to many relationship with a Work Order table (one Visit has many Work Orders). There is a ShipName and a StartDate field in the Visits table. I want to filter the Work Orders list page using a drop down that displays the ShipName and the StartDate sorted first by ShipName and then by StartDate.
After scouring the web, I came up with the following (in visits metadata):
But I keep getting "The sort column 'DisplayVisits' specified for the table 'Visits' does not exist." error on the page at runtime.
So I tried this variation, based on your answer:
This works, but it only sorts by ShipName, not by ShipName then StartDate.
You mentioned that using the override methods is perferred, so how can I do it by using, and then sorting two fields?
sjnaughton
All-Star
27308 Points
5458 Posts
MVP
Re: DisplayFormatAttribute doesn't work when this is a ForeignKey DropDownList / Hyperlink
Dec 13, 2012 09:17 AM|LINK
Yes this works I use it all the time. you cannot sort by two column using the DisplayColumn attribute, I recently created a multi column sort attribute and extension method see below:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class MultiColumnSortAttribute : Attribute { private char[] splitChars = new char[] { ',' }; public Dictionary<String, SortDirection> Columns { get; set; } public MultiColumnSortAttribute(params String[] columns) { Columns = columns.ToDictionary(x => x.Split(splitChars)[0], x => x.Split(splitChars)[1].ToEnum<SortDirection>()); }it's not quite ready for prime time but it will add the sort to your project
public static class QueryExtenderExtensionMethods { /// <summary> /// Sets the initial sort order. /// </summary> /// <param name="queryExtender">The query extender.</param> /// <param name="table">The table.</param> public static void SetInitialSortOrder(this QueryExtender queryExtender, MetaTable table) { var multiColumnSort = table.GetAttribute<MultiColumnSortAttribute>(); if (multiColumnSort != null) { var firstEntry = multiColumnSort.Columns.Keys.First(); var order = new OrderByExpression() { DataField = firstEntry, Direction = multiColumnSort.Columns[firstEntry], }; foreach (var item in multiColumnSort.Columns) { if (item.Key != firstEntry) { order.ThenByExpressions.Add(new ThenBy() { DataField = item.Key, Direction = item.Value }); } } queryExtender.Expressions.Add(order); } else if (table.SortColumn != null) { var order = new OrderByExpression() { DataField = table.SortColumn.Name, Direction = table.SortDescending ? SortDirection.Descending : SortDirection.Ascending, }; queryExtender.Expressions.Add(order); } } }apply the attribute to you metadata in the same place you use the DisplayColumn attribute
Note that these are in pairs I will sort this so it is not magic strings soon.
Hope this helps I will post in full on my blog when done
Always seeking an elegant solution.
sjnaughton
All-Star
27308 Points
5458 Posts
MVP
Re: DisplayFormatAttribute doesn't work when this is a ForeignKey DropDownList / Hyperlink
Dec 20, 2012 01:02 PM|LINK
Oops L I forgot to add the other extension methods, so sorry I’m a dope J so this extension method needs to be in a static class
public static class EnumExtensionMethods { /// <summary> /// Toes the enum. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="enumString">The enum string.</param> /// <returns></returns> /// <remarks></remarks> public static T ToEnum<T>(this String enumString) //where T : Enum { var value = Enum.Parse(typeof(T), enumString); return (T)value; } }I think that should fix it.
Always seeking an elegant solution.
SonnyTate
Member
24 Points
22 Posts
Re: DisplayFormatAttribute doesn't work when this is a ForeignKey DropDownList / Hyperlink
Dec 20, 2012 01:56 PM|LINK
No problem Steve!
This is something that Microsoft should be addressing anyway. It's not unusual in real world applications to have a drop-down that displays more than one column and for both of these columns to be sorted.
Dynamic Data is a great idea, but it seems to me that Microsoft still hasn't taken it far enough to be practical for production level applications. Maybe that is why it hasn't been fully embraced by the ASP.NET developer community. Hopefully this issue, along with several other short-comings will be addressed in future releases.
You've been addressing other Dynamic Data issues as well and you shouldn't be doing this all by yourself. This might be hard to believe, but I'm sure that you, like other developers, have a life beyond just writing code! We simply don't have enough time work our regular jobs and write code for Microsoft in our free time!
Anyway, thanks for all of your effort!