C# wpf caliburn.Micro MahApps HamburgerMenu.ContentTemplate data binding is not working
Asked Answered
S

1

8

I'm making an application using Caliburn.Micro(for easy data binding and stuff) and MahApps.Metro(for designing).

I've created a View name 'MainView' which has HamburgerMenu of MahApps. My issue is data binding is working fine under HamburgerMenu.ContentTemplate tag

Here is my HamburgerMenu.ContentTemplate xaml.

<Page x:Class="Sample.Views.MainView"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:cal="http://www.caliburnproject.org"
      xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
      xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
      xmlns:utils="clr-namespace:Omni.WindowsClient.Utils"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:local="clr-namespace:Omni.WindowsClient.Views"
      mc:Ignorable="d"
      d:DesignHeight="300"
      d:DesignWidth="600">

    <Page.Resources>
        <DataTemplate x:Key="HamburgerMenuItem"
                      DataType="{x:Type mah:HamburgerMenuItem}">
            <Grid Height="48">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="48" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Image Margin="12"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       Source="{Binding Glyph}"
                       Stretch="UniformToFill" />
                <TextBlock Grid.Column="1"
                           VerticalAlignment="Center"
                           FontSize="16"
                           Foreground="White"
                           Text="{Binding Label}" />
            </Grid>
        </DataTemplate>
    </Page.Resources>

    <Grid>

        <mah:HamburgerMenu x:Name="HamburgerMenuControl"
                           SelectedIndex="0"
                           ItemTemplate="{StaticResource HamburgerMenuItem}"
                           OptionsItemTemplate="{StaticResource HamburgerMenuItem}"
                           IsPaneOpen="True"
                           DisplayMode="CompactInline"
                           cal:Message.Attach="[Event ItemClick] = [Action ShowDetails(HamburgerMenuControl.SelectedItem)]"
                           DataContext="{Binding RelativeSource={RelativeSource self}}">
            <mah:HamburgerMenu.ItemsSource>
                <mah:HamburgerMenuItemCollection>
                    <mah:HamburgerMenuItem Label="System Status">
                        <mah:HamburgerMenuItem.Tag>
                            <iconPacks:PackIconFontAwesome Width="22"
                                                           Height="22"
                                                           HorizontalAlignment="Center"
                                                           VerticalAlignment="Center"
                                                           Kind="Tasks" />
                        </mah:HamburgerMenuItem.Tag>
                    </mah:HamburgerMenuItem>
                    <mah:HamburgerMenuItem Label="Inbox">
                        <mah:HamburgerMenuItem.Tag>
                            <iconPacks:PackIconFontAwesome Width="22"
                                                           Height="22"
                                                           HorizontalAlignment="Center"
                                                           VerticalAlignment="Center"
                                                           Kind="Inbox" />
                        </mah:HamburgerMenuItem.Tag>
                    </mah:HamburgerMenuItem>
                        <mah:HamburgerMenuItem.Tag>
                            <iconPacks:PackIconFontAwesome Width="22"
                                                           Height="22"
                                                           HorizontalAlignment="Center"
                                                           VerticalAlignment="Center"
                                                           Kind="Certificate" />
                        </mah:HamburgerMenuItem.Tag>
                    </mah:HamburgerMenuItem>
                </mah:HamburgerMenuItemCollection>
            </mah:HamburgerMenu.ItemsSource>

            <mah:HamburgerMenu.ContentTemplate>
                <DataTemplate DataType="{x:Type mah:HamburgerMenuItem}">
                    <Grid utils:GridUtils.RowDefinitions="48,*">
                        <!--cal:Action.TargetWithoutContext="{Binding ElementName=HamburgerMenuControl, Path=DataContext}"-->
                        <Border Grid.Row="0"
                                Background="{DynamicResource MahApps.Metro.HamburgerMenu.PaneBackgroundBrush}">
                            <TextBlock x:Name="Header"
                                       HorizontalAlignment="Center"
                                       VerticalAlignment="Center"
                                       FontSize="24"
                                       Foreground="White" />
                            <!--Text="{Binding Path=Header, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"-->
                        </Border>
                        <Frame Grid.Row="1"
                               cal:Message.Attach="RegisterFrame($source)"
                               DataContext="{x:Null}"
                               NavigationUIVisibility="Hidden" />
                    </Grid>
                </DataTemplate>
            </mah:HamburgerMenu.ContentTemplate>

        </mah:HamburgerMenu>

    </Grid>
</Page>

and respective view model code is:

using Caliburn.Micro;
using MahApps.Metro.Controls;
using System.Windows.Controls;

namespace Sample.ViewModels
{
    public class MainViewModel : Screen
    {
        private readonly SimpleContainer _container;
        private INavigationService _navigationService;
        private string _header;

        public string HeaderTitle
        {
            get { return _header; }
            set
            {
                _header = value;
                NotifyOfPropertyChange();
            }
        }

        public MainViewModel(SimpleContainer container)
        {
            this._container = container;
            DisplayName = "Main";
        }

        public void RegisterFrame(Frame frame)
        {
            _navigationService = new FrameAdapter(frame);
            _container.Instance(_navigationService);
            _navigationService.NavigateToViewModel(typeof(SystemStatusViewModel));
            HeaderTitle = "System Status";
        }

        public void ShowDetails(HamburgerMenuItem menuItem)
        {
            switch (menuItem.Label)
            {
                case "System Status":
                    _navigationService.NavigateToViewModel(typeof(SystemStatusViewModel));
                    HeaderTitle = "System Status";
                    break;
                case "Inbox":
                    _navigationService.NavigateToViewModel(typeof(InboxViewModel));
                    HeaderTitle = "Inbox";
                    break;
                default:
                    break;
            }
        }

    }
}

I want to change View in frame under HamburgerMenu.ContentTemplate when I click on menu item. Like System Status view is SystemStatusView and Inbox view is InboxView.

My code is working fine (it changes the view in frame and change the Header label too) if I don't use HamburgerMenu.ContentTemplate. But I want to use HamburgerMenu.ContentTemplate to work with HamburgerMenu.

Thanks!

Sarette answered 9/9, 2017 at 18:35 Comment(1)
You need to be more specific about what isn't working. What behavior are you seeing when you use ContentTemplate? I have reproduced your code as best I could, and when I click a menu item, the frame navigates to the expected view model.Durwin
S
2

If it's working fine if you don't use HamburgerMenu.ContentTemplate, but stops working when you do, the problem is probably with you overwriting the default template in a way that doesn't support all functionalities of a control.

I'd suggest you to use Blend to get the default HamburgerMenu.ContentTemplate, then just edit it to your needs, without changing too much (keep in mind that names of controls used as a template may have a crucial meaning, so be careful what you are editing).

If you don't know how to use Blend to get your control's template, here is a simple tutorial described in a documentation of Telerik controls (don't worry, it works the same for all controls). You just need to create copy of a HamburgerMenu.ContentTemplate, paste it to your application and you are good to go (editing).

Seabee answered 13/9, 2017 at 8:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.