At our company, we're used to develop our applications using WinForms, Now we decided to switch to WPF-MVVM with Caliburn.Micro and Modern UI. The thing we're trying to reach is to have a small application that has: - 1 Modern Window - 2 Pages inside that Modern window the goal is to have a button inside that page that navigates the Modern Window to the second page with parameters.
I've been working trying to understand how to work this out, I succeeded with the Window (without the MUI), but when it comes to MUI, it's not really giving me the result we want.
So far, All I did, is
- Create a new MUI Project
- Add the Caliburn.Micro to the project
Change the App.xaml to
<Application x:Class="MuiWithCaliburn01.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MuiWithCaliburn01"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary> <local:AppBootstrapper x:Key="bootstrapper" /> <local:ModernContentLoader x:Key="ModernContentLoader" /> </ResourceDictionary> <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" /> <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.Light.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources>
Create the Bootstrapper Class
public class AppBootstrapper : BootstrapperBase { static AppBootstrapper() { } public AppBootstrapper() { Initialize(); } protected override void OnStartup(object sender, StartupEventArgs e) { DisplayRootViewFor(); } }
Create the ModernContentLoader Class
public class ModernContentLoader : DefaultContentLoader { protected override object LoadContent(Uri uri) { var content = base.LoadContent(uri); if (content == null) return null; var vm = Caliburn.Micro.ViewModelLocator.LocateForView(content); if (vm == null) return content; if (content is DependencyObject) { Caliburn.Micro.ViewModelBinder.Bind(vm, content as DependencyObject, null); } return content; } }
ModernWindowView.xaml & ModernWindowViewModel.cs
< mui:ModernWindow x:Class="MuiWithCaliburn01.ModernWindowView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mui="http://firstfloorsoftware.com/ModernUI" ContentLoader="{StaticResource ModernContentLoader}"> < mui:ModernWindow.MenuLinkGroups> < mui:LinkGroupCollection> < mui:LinkGroup DisplayName="Hello"> < mui:LinkGroup.Links> < mui:Link Source="Child1View.xaml" DisplayName="Click me">< /mui:Link> < /mui:LinkGroup.Links> < /mui:LinkGroup> < /mui:LinkGroupCollection> < /mui:ModernWindow.MenuLinkGroups> < /mui:ModernWindow>
class ModernWindowViewModel : Conductor.Collection.OneActive { public ModernWindowViewModel() { //this function is doing nothing in the ModernWindow, but it works great in the Window. ActivateItem(new Child1ViewModel()); } }
And finally, the Child1View.xaml
<UserControl x:Class="MuiWithCaliburn01.Child1View" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mui="http://firstfloorsoftware.com/ModernUI" mc:Ignorable="d" xmlns:cal="http://www.caliburnproject.org" xmlns:model="clr-namespace:MuiWithCaliburn01" d:DataContext="{x:Type model:Child1ViewModel}" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <Button cal:Message.Attach="ClickMe" Width="140" Height="50">Hello World</Button> </Grid> </UserControl>
and Child1ViewModel.cs
public class Child1ViewModel : Conductor<IScreen> { public void ClickMe() { MessageBox.Show("Hello"); } }
My question is, step 6, why does the function do nothing? and if my way is wrong can anybody direct me to a better way?
And if it's the best approach, how can I navigate from the function ClickMe to another View.