I've managed to get Caliburn Micro to work nicely with Blend at design-time, using d:DesignInstance, by modifying the bootstrapper as follow:
///<summary>
/// Overriding only to avoid a design-time error (see below)
///</summary>
///<returns></returns>
protectedoverride IEnumerable<Assembly> SelectAssemblies()
{
if (Execute.InDesignMode)
{
var appDomain = AppDomain.CurrentDomain;
var assemblies = appDomain.GetType()
.GetMethod("GetAssemblies")
.Invoke(appDomain,
null) as Assembly[] ??
new Assembly[] {};
// the following original line raises an exception at design time so I've commented it and substituted for the lines that follow
// var applicationAssembly = assemblies.LastOrDefault(x => !x.IsDynamic && x.GetExportedTypes().Any(t => t.IsSubclassOf(typeof(Application))));
var applicationAssemblies =
new List<Assembly>();
foreach (var assemblyin assemblies)
{
try
{
if (!assembly.IsDynamic && assembly.GetExportedTypes().Any(t => t.IsSubclassOf(typeof (Application))))
applicationAssemblies.Add(assembly);
}
catch (Exception)
{
}
}
return applicationAssemblies;
}
returnnew[] {Application.Current.GetType().Assembly};
}
///<summary>
/// Overriding to allow design-time ViewModel resolution
///</summary>
protectedoverridevoid StartDesignTime()
{
base.StartDesignTime();
var actual = ViewModelBinder.Bind;
ViewModelBinder.Bind = (viewModel, view, context) =>
{
var vmType = viewModel.GetType();
// when using d:DesignInstance, Blend tries to assign the DesignInstanceExtension class as the DataContext, so here we
// get the actual ViewModel which is in the Instance property of DesignInstanceExtension
if (vmType.FullName == "Microsoft.Expression.DesignModel.InstanceBuilders.DesignInstanceExtension")
{
var propInfo = vmType.GetProperty("Instance", BindingFlags.Instance | BindingFlags.NonPublic);
viewModel = propInfo.GetValue(viewModel,
null);
}
actual(viewModel, view, context);
};
}
Hope this helps anyone with design-time issues.