Search code examples
wpfmvvmcrossmahapps.metro

Can MahApps.Metro be used in MvvmCross?


I was trying to use Mahapps Metro inside a WPF project using MvvmCross mvvm framework.

Both seem to use custom window control. Is there a way to use both in a project?

Metro window:

<mah:MetroWindow  x:Class="TipCalc.WPF.MainWindow"
              xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              xmlns:local="clr-namespace:TipCalc.WPF"
              xmlns:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
              mc:Ignorable="d"
              Title="MainWindow"
              Height="450"
              Width="800">
    <Grid>
    </Grid>
</mah:MetroWindow>

MvvmCross Window:

<views:MvxWindow  x:Class="TipCalc.WPF.MainWindow"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              xmlns:local="clr-namespace:TipCalc.WPF"
              xmlns:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
              mc:Ignorable="d"
              Title="MainWindow"
              Height="450"
              Width="800">
    <Grid>
    </Grid>
</views:MvxWindow>

The application runs either way. But with the Metro window in place, the rest of the application doesn't get set up(ie.-children views). With the MvvmCross window in place, the application works as usual but is not designed or colored.


Solution

  • Since multi inheritance is not supported in C#, this is not possible out of the box.

    But a look at the source code of MvxWindow shows it's no big class. So a potential solution could be creation of your own window. This window, let's call it MvxMetroWindow, could collect both functionalities by inheriting from MetroWindow and aditionally all the source code of MvxWindow added (copied from the original source code) by yourself.

    This would look like this:

    using System;
    using System.Windows;
    
    using MahApps.Metro.Controls;
    
    using MvvmCross;
    using MvvmCross.Binding.BindingContext;
    using MvvmCross.Platforms.Wpf.Views;
    using MvvmCross.ViewModels;
    using MvxApplication = MvvmCross.Platforms.Wpf.Views.MvxApplication;
    
    namespace TipCalc.WPF
    {
        public class MvxMetroWindow : MetroWindow, IMvxWindow, IMvxWpfView, IDisposable
        {
            private IMvxViewModel _viewModel;
            private IMvxBindingContext _bindingContext;
            private bool _unloaded = false;
            //... Further implemenetation of original MvxWindow
        }
    }
    

    The custom window finally can be used like this:

    <local:MvxMetroWindow x:Class="TipCalc.WPF.MainWindow"
                          xmlns:local="clr-namespace:TipCalc.WPF"
                          ...