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
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.
As for your first question about why does the function do nothing, I think it may have to do with the hierarchy of your project. Using MUI this is the main (and only) window for one of my applications
<mui:ModernWindow x:Class="namespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
Title="Window Title" IsTitleVisible="True"
ContentSource="/Pages/Home.xaml"
Style="{StaticResource MyModernWindow}">
<mui:ModernWindow.TitleLinks>
<mui:Link DisplayName="settings" Source="/Pages/SettingsPage.xaml" />
</mui:ModernWindow.TitleLinks>
in my project hierarchy, i have my project root (CSPROJ file), MainWindow.xaml then a Pages folder. Inside my pages folder i have my SettingsPage.xaml. The source attribute in my mui:Link tag points to the realitive path of my main window to my settingsPage.xaml file. MUI will then load and display that path in the content provider that is put in your main window for you by the MUI ModernWindow class default style template. No additional code is needed on your part to navigate (until you want complex sub view navigation).
my settingsPage.xaml file is a normal user control with the grid having a style assigned to the ContentRoot static resource style as it also will contain additional views/pages.
Mui source can be found on GitHub at Mui GithubLink. Here you can download the sample program, who's code is found in the same repository under app Link here for covience.
I am not familiar with Caliburn.Micro so i'm not sure how the two integrate together, such as requirements of Caliburn.Micro to function. I do know how MUI integrates with MVVM light and there are many examples of this found on the internet in my research before hand.
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