Often I find myself filling ASP.NET repeaters with items that need the CSS class set depending on index: 'first' for index 0, 'last' for index (length-1), and 'mid' in the middle:
_repeater.DataSource = from f in foos
select new
{
...,
CssClass = MakeCssClass( foos, f )
};
private static string MakeCssClass( Foo[] foos, Foo f )
{
var index = Array.IndexOf( foos, f );
if( index == 0 )
{
return "first";
}
else if( index == foos.Length - 1 )
{
return "last";
}
else
{
return "mid";
}
}
Is there a nicer way I can achieve this (eg using lambda functions)? If I try I get CS0828, "Cannot assign lambda expression to anonymous type property".
-
You might be interested in my SmartEnumerable type in MiscUtil.
From the usage page, there's an example:
using System; using System.Collections.Generic; using MiscUtil.Collections; class Example { static void Main(string[] args) { List<string> list = new List<string>(); list.Add("a"); list.Add("b"); list.Add("c"); list.Add("d"); list.Add("e"); foreach (SmartEnumerable<string>.Entry entry in new SmartEnumerable<string>(list)) { Console.WriteLine ("{0,-7} {1} ({2}) {3}", entry.IsLast ? "Last ->" : "", entry.Value, entry.Index, entry.IsFirst ? "<- First" : ""); } } }With implicitly typed variables and a bit more type inference the syntax could be tidied up quite easily. I must get round to that some time, but the basics are already there.
stusmith : Lovely, thanks. I added a helper method to SmartEnumerable.Entry: public V FirstMidLast( V first, V mid, V last ) { if( IsFirst ) { return first; } else if( IsLast ) { return last; } else { return mid; } } -
Here's a clever way to get those mids - Skip, Reverse, Skip (what is this, UNO?).
List<SomeClass> myList = foos .Select(f => new SomeClass{ ..., CssClass=string.Empty }) .ToList(); if (myList.Any()) { myList.First().CssClass = "first"; myList.Last().CssClass = "last"; foreach(var z in myList.Skip(1).Reverse().Skip(1)) { z.CssClass = "mid"; } } _repeater.DataSource = myList;Here's a better way for this problem statement.
List<SomeClass> myList = foos .Select(f => new SomeClass{ ..., CssClass="mid" }) .ToList(); if (myList.Any()) { myList.First().CssClass = "first"; myList.Last().CssClass = "last"; } _repeater.DataSource = myList;Of course, neither of these technique will work if you are using anonymous types (their properties are read-only). Don't use anonymous types for query results.
stusmith : I prefer anonymous types, as it gives you a certain amount of compile-time checking between database schema and ASP.NET pages.
0 comments:
Post a Comment