psychoric still trying to figure out what this blog is about

Happy new year to my family, beloved wife and friends all over the world! Love you all!
17Apr/080

C# Generic Comparer

This morning I ran into a situation where i need to sort an array of ServiceController before binding into a combobox. So I looked around and I found Array.Sort (or List.Sort). Tried with the parameter-less call, but .NET doesn't like it. One of the required overloaded methods requires a IComparer. Hmm, looks familiar and found some straightforward examples online. Immediately I have a simple class that solves my problem.

private class ServiceControllerSort : IComparer<ServiceController>
{
	public int Compare(ServiceController x, ServiceController y)
	{
		return string.Compare(x.DisplayName, y.DisplayName, true);
	}
}

Now what? What if next time I want to sort on my ExtendedServiceController class (as if there is necessity to do one)? I will have more and more IComparer implementations. I decided to explore further and this page says it all. Took the code, clean it up and woots, I have a generic comparison class that is usable for almost all types.

/// <summary>
/// Custom sorter based on property
/// </summary>
/// <typeparam name="T">Target Type</typeparam>
public class ExtSortComparer<T>: IComparer<T>
{
	private ListSortDirection _sortDirection = ListSortDirection.Ascending;
	private PropertyDescriptor _targetPropDescriptor;
 
	/// <summary>
	/// Constructor
	/// </summary>
	public ExtSortComparer()
	{
	}
 
	/// <summary>
	/// Constructor
	/// </summary>
	/// <param name="PropertyName">Name of property to sort on. Case sensitive.</param>
	public ExtSortComparer(string PropertyName)
	{
		_targetPropDescriptor = TypeDescriptor.GetProperties(typeof(T))[PropertyName];
	}
 
	/// <summary>
	/// Constructor
	/// </summary>
	/// <param name="PropertyName">Name of property to sort on. Case sensitive.</param>
	/// <param name="SortDirection">Sort direction</param>
	public ExtSortComparer(string PropertyName, ListSortDirection SortDirection) : this(PropertyName)
	{
		_sortDirection = SortDirection;
	}
 
	/// <summary>
	/// Constructor
	/// </summary>
	/// <param name="TargetProperty">Descriptor of property to sort on</param>
	public ExtSortComparer(PropertyDescriptor TargetProperty)
	{
		_targetPropDescriptor = TargetProperty;
	}
 
	/// <summary>
	/// Constructor
	/// </summary>
	/// <param name="TargetProperty">Descriptor of property to sort on</param>
	/// <param name="SortDirection">Sort direction</param>
	public ExtSortComparer(PropertyDescriptor TargetProperty, ListSortDirection SortDirection)
	{
		_targetPropDescriptor = TargetProperty;
		_sortDirection = SortDirection;
	}
 
	/// <summary>
	/// Compare two given object
	/// </summary>
	/// <param name="x">Object A</param>
	/// <param name="y">Object B</param>
	/// <returns>Result of comparison</returns>
	public int Compare(T x, T y)
	{
		//ensure there is proper property description
		if (_targetPropDescriptor != null)
		{
			int intRetValue = _CompareValues(_targetPropDescriptor.GetValue(x), 
											_targetPropDescriptor.GetValue(y));
 
			//reverse the sorting if descending
			if (_sortDirection == ListSortDirection.Descending)
				return intRetValue * -1;
 
			return intRetValue; //return the result
		}
 
		return 0; //return neutral if insufficient information to sort
	}
 
	/// <summary>
	/// Compare values of target property
	/// </summary>
	/// <param name="ValueX">Value of property (Object A)</param>
	/// <param name="ValueY">Value of property (Object B)</param>
	/// <returns>Result of comparison</returns>
	private int _CompareValues(object ValueX, object ValueY)
	{
		if (ValueX is IComparable) //if X can be compared
			return ((IComparable)ValueX).CompareTo(ValueY);
 
		if (ValueY is IComparable) //else if Y can be compared
			return ((IComparable)ValueY).CompareTo(ValueX);
 
		//when both can't be compared, resort to string value.
		return ValueX.ToString().CompareTo(ValueY.ToString());
	}
}

The comments should explain what is happening internally. Another good addition to my common library! If you have any thoughts, shoot!

Filed under: Coder's Code No Comments
8Apr/083

New accessories: Pop-up flash diffuser

Been very long time since i bought any camera stuff and i came across this should-be-useful item while surfing with no aim. I managed to find it at one of the local online store and instantly made an order. The total damage, RM40. The item reached my hand today (prompt shipping, thumbs up!) so immediately ran a test trial with it. Let the results speak themselves

Without With
_MG_6043 _MG_6047
_MG_6050 _MG_6049
_MG_6057 _MG_6059
_MG_6051 _MG_6052

So what do you think? Is it worth the purchase? I think it does coz sometimes you wouldn't want a harsh light especially on closer subjects.

Filed under: Psycho's Note 3 Comments