Reputation: 403
In the control ObjectListView(http://objectlistview.sourceforge.net/html/cookbook.htm), I'm trying to add a custom sorter where it ignores "The" and "A" prefixes.
I managed to do it with a regular ListView, but now that I switched to ObjectListView(a lot more features, and ease), I can't seem to do the same.
The following is the Main comparer in the ObjectListView code i think...
public int Compare(object x, object y)
{
return this.Compare((OLVListItem)x, (OLVListItem)y);
}
Original Sorter for ascending, as an example (Ignoring "A" and "The")
public class CustomSortAsc : IComparer
{
int IComparer.Compare(Object x, Object y)
{
string[] px = Convert.ToString(x).Split(' ');
string[] py = Convert.ToString(y).Split(' ');
string newX = "";
string newY = "";
for (int i = 0; i < px.Length; i++)
{
px[i] = px[i].Replace("{", "");
px[i] = px[i].Replace("}", "");
}
for (int i = 0; i < py.Length; i++)
{
py[i] = py[i].Replace("{", "");
py[i] = py[i].Replace("}", "");
}
if ((px[1].ToLower() == "a") || (px[1].ToLower() == "the"))
{
if (px.Length > 1)
{
for (int i = 2; i < px.Length; i++)
newX += px[i];
}
}
else
{
for (int i = 1; i < px.Length; i++)
newX += px[i];
}
if ((py[1].ToLower() == "a") || (py[1].ToLower() == "the"))
{
if (py.Length > 1)
{
for (int i = 2; i < py.Length; i++)
newY += py[i];
}
}
else
{
for (int i = 1; i < py.Length; i++)
newY += py[i];
}
return ((new CaseInsensitiveComparer()).Compare(newX, newY));
}
Upvotes: 1
Views: 2989
Reputation: 19020
Although it has nothing directly to do with your problem may I suggest some code improvements? Apparently your original x and y objects are space separated words. Not sure if it is intentional that you don't re-join them with spaces but I've kept it like that.
public static class Extensions
{
public static IEnumerable<T> SkipIf<T>(this IEnumerable<T> items, Predicate<T> pred)
{
return pred(items.First()) ? items.Skip(1) : items;
}
}
public class CustomSortAsc : IComparer
{
int IComparer.Compare(Object x, Object y)
{
var ignorePredicates = new List<string> { "a", "the" };
var px = Convert
.ToString(x)
.Replace("{", "")
.Replace("}", "")
.Split(' ')
.SkipIf(s => ignorePredicates.Contains(s.ToLower()))
.ToArray();
var py = Convert
.ToString(y)
.Replace("{", "")
.Replace("}", "")
.Split(' ')
.SkipIf(s => ignorePredicates.Contains(s.ToLower()))
.ToArray();
var newX = string.Join("", px);
var newY = string.Join("", py);
return string.Compare(newX, newY, true);
}
}
You could just use SkipWhile<>
but that would skip multiple "a" and "the" at the beginning. Might be ok - then you don't need the SkipIf<>
extension.
Upvotes: 2
Reputation: 6882
Install a CustomSorter delegate, and in that delegate, put an ListItemSorter onto the ObjectListView
this.incidentListView.CustomSorter = delegate(OLVColumn column, SortOrder order) {
this.incidentListView.ListViewItemSorter = new CustomSortAsc();
};
Better than doing all this work on each comparison, cache the sort value on each of your model objects. If the value is "{The} Whole Nine Yards", store "whole nine yards" and do a simple (and fast) string compare on those values.
ObjectListView does have its own forum.
Upvotes: 1