caliburn.micro how to load and bind view for viewmodel runtime
I am building an application that requires theme support. So I want to supply views folder run time.
public class AppBootstrapper : Bootstrapper<IShell>
{
CompositionContainer _container;
/// <summary>
/// By default, we are configure to use MEF
/// </summary>
protected override void开发者_如何转开发 Configure()
{
//view locator code get views from file and and binding it to viewmodel run time.
}
}
A better tweak would be to use this way (implemented in Caliburn but not the Micro one). http://caliburnmicro.codeplex.com/discussions/265502
First of all you need to define an attribute used to store the relevant data used to discover the view:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public class ViewAttribute : Attribute
{
public object Context { get; set; }
public Type ViewType { get; private set; }
public ViewAttribute(Type viewType)
{
ViewType = viewType;
}
}
Attach it to your View Model.
[View(typeof(MyView))]
public class MyViewModel : Screen
Then, you need to change the LocateTypeForModelType in your bootstrapper to something like this:
void Initialize()
{
var baseLocate = ViewLocator.LocateTypeForModelType;
ViewLocator.LocateTypeForModelType = (modelType, displayLocation, context) =>
{
var attribute = modelType.GetCustomAttributes(typeof(ViewAttribute), false).OfType<ViewAttribute>().Where(x => x.Context == context).FirstOrDefault();
return attribute != null ? attribute.ViewType : baseLocate(modelType, displayLocation, context);
};
}
In Caliburn, you can create a customized IConventionManager or tweek the implementation (DefaultConventionManager) to change the way the framework finds the View folder at runtime.
In fact views should not necessarily be in Views folder and you can modify this default behavior as this is just the default Convention. The best way to implement this interface is to check the default implementation.
精彩评论