Saturday, February 20, 2010

ObservableItemCollection Class

While working with WPF data binding I often found myself populating an ObservableCollection with instances of classes that implement INotifyPropertyChanged, and then subscribing the same method to the PropertyChanged event of each element. To eliminate such boilerplate code, I derived from ObservableCollection to create ObservableItemCollection. When the PropertyChanged event of any element of the the collection is raised, the ObservableItemCollection's own PropertyChanged event is invoked. Coincidentally Microsoft is planning on releasing a similar class with the same name.


using System;
using System.ComponentModel;
using System.Collections.Specialized;
using System.Collections.ObjectModel;

namespace ExploringDotNet
{
public class ObservableItemCollection<T> : ObservableCollection<T>
{
public event PropertyChangedEventHandler ItemPropertyChanged;

void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (ItemPropertyChanged != null)
ItemPropertyChanged(sender, e);
}

protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
foreach (INotifyPropertyChanged i in e.NewItems)
i.PropertyChanged += Item_PropertyChanged;

if (e.OldItems != null)
foreach (INotifyPropertyChanged i in e.OldItems)
i.PropertyChanged -= Item_PropertyChanged;

base.OnCollectionChanged(e);
}
}
}

Wednesday, February 17, 2010

C# Stream Array Merge Extension Method

If the need to sort a collection larger than the amount of RAM available arises, merge sort algorithms are a good solution. The following extension method is a merge algorithm implementation that combines two or more sorted Streams using Read and Output functions passed as parameters.


public static class StreamArrayExtension
{
public static void Merge<T>(this Stream[] Streams,
Func<Stream, T> ReadItem, Action<T> OutputItem)
where T : IComparable<T>
{
T[] buffer = new T[Streams.Length];

for (int x = 0; x < Streams.Length; x++)
buffer[x] = ReadItem(Streams[x]);

int end = Streams.Length - 1;

bool[] completed = new bool[Streams.Length];

int completedCount = 0;

while (completedCount < Streams.Length)
for (int x = 0; x < Streams.Length; x++)
if (completed[x])
continue;
else
for (int y = 0; y < Streams.Length; y++)
if (x == y && x != end)
continue;
else if (!completed[y] &&
buffer[x].CompareTo(buffer[y]) == 1)
break;
else if (y == end)
{
OutputItem(buffer[x]);

if (Streams[x].Position != Streams[x].Length)
buffer[x] = ReadItem(Streams[x]);
else
{
completed[x] = true;

completedCount++;
}
}
}
}


It can be used as follows:

Stream[] sortedStreams = new Stream[]
{
new MemoryStream(new byte[] { 1, 2, 3 }),
new MemoryStream(new byte[] { 0, 4 }),
new MemoryStream(new byte[] { 1, 5 }),
};

sortedStreams.Merge(x => x.ReadByte(), x => Console.WriteLine(x));

Console.ReadKey();


With the resulting output:
0
1
1
2
3
4
5

Tuesday, February 16, 2010

Enumerating ResourceDictionary Keys in Silverlight 2

The Microsoft response to this need is that the feature was not implemented in Silverlight 2. However, enumerating ResourceDictionary Keys is possible through the use of reflection. Aside from the performance cost incurred by reflection, the only other caveat I'm aware of is that the end-user must have the Silverlight 3 runtime installed for this to work.


ResourceDictionary dictionary = new ResourceDictionary()
{
{ "a", "" },
{ "b", "" },
{ "c", "" }
};

PropertyInfo prop = typeof(ResourceDictionary).GetProperty("Keys");
object[] keys = prop.GetValue(dictionary, null) as object[];

foreach (object o in keys)
MessageBox.Show(o.ToString());