A couple of days ago i presented you the TypedList which supports navigation through subproperties. Another common feature request is the possibility to add a column that has a value based on other values in the row (like a DataColumn with it’s Expression property set). With the plumbing code i’ve written it’s as simple as implementing the following interface:
public interface IExpressionProvider<ComponentType, PropertyType>
{
/// <summary>
/// Gets the name of the property
/// </summary>
string Name { get; }
/// <summary>
/// Returns the value of the expression for the given component
/// </summary>
/// <param name="component"></param>
/// <returns></returns>
PropertyType GetValue(ComponentType component);
}
An example implementation could be an expression that represents the duration of an Appointment:
public class DurationExpressionProvider : IExpressionProvider<Appointment, TimeSpan>
{
#region IExpressionProvider<Appointment,TimeSpan> Members
public string Name { get { return "||Duration"; } }
public TimeSpan GetValue(Appointment component)
{
return component.DateTimeRange.End - component.DateTimeRange.Start;
}
#endregion
}
I’ve changed the constructor of TypedList a bit so that it accepts an enumeration of PropertyDescriptors. In my example you can initialise the list as following:
List<PropertyDescriptor> propertyDescriptors = new List<PropertyDescriptor>();
// create the subpropertydescriptors
string[] propertyNames = new string[] { "Patient.Name", "Patient.Address.Municipality", "DateTimeRange.Start", "DateTimeRange.End" };
propertyDescriptors.AddRange(Array.ConvertAll<string, SubPropertyDescriptor<Appointment>>(propertyNames, delegate(string propertyName) { return new SubPropertyDescriptor<Appointment>(propertyName); }));
// add an expressiondescriptor
IExpressionProvider<Appointment, TimeSpan> expressionProvider = new DurationExpressionProvider();
ExpressionDescriptor<Appointment, TimeSpan> durationDescriptor = new ExpressionDescriptor<Appointment, TimeSpan>(expressionProvider);
propertyDescriptors.Add(durationDescriptor);
TypedBindingList<Appointment> appointments = new TypedBindingList<Appointment>(propertyDescriptors);
And this is how it looks like at runtime:

As always, feel free to download the code: TypedList.zip.