Well im trying to use MahApps.Metro and Caliburn.Micro together but im getting some problems
Here is my bootstrapper
public sealed class TestBootstrapper : Bootstrapper<ShellViewModel>
{
private CompositionContainer container;
protected override void Configure()
{
container = new CompositionContainer(new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()));
CompositionBatch batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new AppWindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue(container);
container.Compose(batch);
}
protected override object GetInstance(Type serviceType, string key)
{
string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
var exports = container.GetExportedValues<object>(contract);
if (exports.Count() > 0)
{
return exports.First();
}
return base.GetInstance(serviceType, key);
}
}
And here is my AppWindowManager
public sealed class AppWindowManager : WindowManager
{
static readonly ResourceDictionary[] resources;
static AppWindowManager()
{
resources = new ResourceDictionary[]
{
new ResourceDictionary
{ Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Colours.xaml", UriKind.RelativeOrAbsolute) },
new ResourceDictionary
{ Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml", UriKind.RelativeOrAbsolute) },
new ResourceDictionary
{ Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml", UriKind.RelativeOrAbsolute) },
new ResourceDictionary
{ Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml", UriKind.RelativeOrAbsolute) },
new ResourceDictionary
{ Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml", UriKind.RelativeOrAbsolute) },
new ResourceDictionary
{ Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Controls.AnimatedTabControl.xaml", UriKind.RelativeOrAbsolute) }
};
}
protected override Window EnsureWindow(object model, object view, bool isDialog)
{
MetroWindow window = view as MetroWindow;
if (window == null)
{
window = new MetroWindow()
{
Content = view,
SizeToContent = SizeToContent.WidthAndHeight
};
window.MinHeight = 150;
window.MinWidth = 500;
foreach (ResourceDictionary resourceDictionary in resources)
{
window.Resources.MergedDictionaries.Add(resourceDictionary);
}
window.SetValue(View.IsGeneratedProperty, true);
Window owner = this.InferOwnerOf(window);
if (owner != null)
{
window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
window.Owner = owner;
}
else
{
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
}
}
else
{
Window owner2 = this.InferOwnerOf(window);
if (owner2 != null && isDialog)
{
window.Owner = owner2;
}
}
return window;
}
}
This works somewhat but i get a black border around my window until i resize see image below
Why is there a black border and how can i get rid of it (If i manually resize the window the border goes away.)?
With Caliburn.Micro 2 and Mahapps.Metro 1 the above is no longer a valid combination of the two frameworks.
After some digging through Caliburn.Micro documentations and following out dated guides I came up with the following.
First create the bootstrapper like so:
public class AppBootstrapper : BootstrapperBase
{
private CompositionContainer container;
public AppBootstrapper()
{
Initialize();
}
protected override void Configure()
{
container = new CompositionContainer(
new AggregateCatalog(
AssemblySource.Instance.Select(
x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()
)
);
CompositionBatch batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new WindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue(container);
container.Compose(batch);
}
protected override object GetInstance(Type service, string key)
{
string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(service) : key;
var exports = container.GetExportedValues<object>(contract);
if(exports.Any())
{
return exports.First();
}
throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.GetExportedValues<object>(AttributedModelServices.GetContractName(service));
}
protected override void BuildUp(object instance)
{
container.SatisfyImportsOnce(instance);
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<IShell>();
}
}
Next add the bootstrapper to the App.xaml file along with the MahApps.Metro resources like so:
<Application x:Class="your-namespace.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:your-namespace">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<local:AppBootstrapper x:Key="bootstrapper" />
</ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
The next step is to ensure your ShellViewModel has the proper exports (this is simple requirements for setting up mef bootstrapper, and don't forget to create the IShell class (not going to show that here as it is standard)) like so:
[Export(typeof(IShell))]
public class ShellViewModel : PropertyChangedBase, IShell
{
}
Last but not least we need to setup the ShellView to use the MahApps.Metro Window:
<Controls:MetroWindow x:Class="your-namespace.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro">
<Grid Background="White">
<TextBlock Text="Hello Caliburn Micro!"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="20" />
</Grid>
</Controls:MetroWindow>
Hope this helps anyone else looking to combine Caliburn.Micro and MahApps.Metro in their latest iterations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With