Here is some code to extract the icons from the System.Activities.Presentation DLL, which is distributable. I'm looking for performance tips on this as it's a bit slow.
protected void LoadToolBox()
{
var dict = new ResourceDictionary {Source = new Uri("pack://application:,,,/System.Activities.Presentation;component/themes/icons.xaml")};
Resources.MergedDictionaries.Add(dict);
var builder = new AttributeTableBuilder();
var standtypes = typeof(Activity).Assembly.GetTypes().
Where(t => typeof(Activity).IsAssignableFrom(t) && !t.IsAbstract && t.IsPublic && !t.IsNested && t.HasDefaultConstructor());
var smtypes = typeof(Receive).Assembly.GetTypes().
Where(t => typeof(Activity).IsAssignableFrom(t) && !t.IsAbstract && t.IsPublic && !t.IsNested && t.HasDefaultConstructor());
var types = typeof(FileToString).Assembly.GetTypes().
Where(t => typeof(Activity).IsAssignableFrom(t) && !t.IsAbstract && t.IsPublic);
var primary = new ToolboxCategory("Microsoft Primary");
var secondary = new ToolboxCategory("Microsoft Secondary");
foreach (var type in standtypes.OrderBy(t => t.Name))
{
var w = new ToolboxItemWrapper(type, type.ToGenericTypeString());
if (AddIcon(type, builder))
{
secondary.Add(w);
}
else
{
primary.Add(w);
}
}
var sm = new ToolboxCategory("Microsoft ServiceModel");
foreach (var type in smtypes.OrderBy(t => t.Name))
{
AddIcon(type, builder);
var w = new ToolboxItemWrapper(type, type.ToGenericTypeString());
sm.Add(w);
}
var cat = new ToolboxCategory("Custom");
foreach (var type in types.OrderBy(t => t.Name))
{
var w = new ToolboxItemWrapper(type, type.ToGenericTypeString());
cat.Add(w);
}
MetadataStore.AddAttributeTable(builder.CreateTable());
tbc.Categories.Add(primary);
tbc.Categories.Add(secondary);
tbc.Categories.Add(sm);
tbc.Categories.Add(cat);
}
protected bool AddIcon(Type type, AttributeTableBuilder builder)
{
var secondary = false;
var tbaType = typeof(ToolboxBitmapAttribute);
var imageType = typeof(System.Drawing.Image);
var constructor = tbaType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { imageType, imageType }, null);
string resourceKey = type.IsGenericType ? type.GetGenericTypeDefinition().Name : type.Name;
int index = resourceKey.IndexOf('`');
if (index > 0)
{
resourceKey = resourceKey.Remove(index);
}
if (resourceKey == "Flowchart")
{
resourceKey = "FlowChart"; // it appears that themes/icons.xaml has a typo here
}
resourceKey += "Icon";
Bitmap small, large;
object resource = TryFindResource(resourceKey);
if (!(resource is DrawingBrush))
{
resource = FindResource("GenericLeafActivityIcon");
secondary = true;
}
var dv = new DrawingVisual();
using(var context = dv.RenderOpen())
{
context.DrawRectangle(((DrawingBrush)resource), null, new Rect(0, 0, 32, 32));
context.DrawRectangle(((DrawingBrush)resource), null, new Rect(32, 32, 16, 16));
}
var rtb = new RenderTargetBitmap(32, 32, 96, 96, PixelFormats.Pbgra32);
rtb.Render(dv);
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new PngBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(rtb));
enc.Save(outStream);
outStream.Position = 0;
large = new Bitmap(outStream);
}
rtb = new RenderTargetBitmap(16, 16, 96, 96, PixelFormats.Pbgra32);
dv.Offset = new Vector(-32, -32);
rtb.Render(dv);
using (var outStream = new MemoryStream())
{
BitmapEncoder enc = new PngBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(rtb));
enc.Save(outStream);
outStream.Position = 0;
small = new Bitmap(outStream);
}
var tba = constructor.Invoke(new object[] { small, large }) as ToolboxBitmapAttribute;
builder.AddCustomAttributes(type, tba);
return secondary;
}
public static string ToGenericTypeString(this Type t)
{
if (!t.IsGenericType)
return t.Name;
string genericTypeName = t.GetGenericTypeDefinition().Name;
genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`'));
string genericArgs = string.Join(",", t.GetGenericArguments().Select(ToGenericTypeString));
return genericTypeName + "<" + genericArgs + ">";
}
public static bool HasDefaultConstructor(this Type t)
{
return t.GetConstructors().Where(c => c.GetParameters().Length <= 0).Count() > 0;
}