2017-09-09 5 views
8

Ich mache eine Anwendung mit Caliburn.Micro (für einfache Datenbindung und Zeug) und MahApps.Metro (für das Entwerfen).C# wpf caliburn.Micro MahApps HamburgerMenu.ContentTemplate Datenbindung funktioniert nicht

Ich habe einen View-Namen 'MainView' erstellt, der HamburgerMenu von MahApps hat. Mein Problem ist Datenbindung funktioniert gut unter HamburgerMenu.ContentTemplate Tag

Hier ist meine 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> 

und entsprechende Ansicht Modellcode ist:

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; 
      } 
     } 

    } 
} 

ich in Rahmen ändern, unter HamburgerMenu.ContentTemplate anzeigen möchten, wenn ich auf den Menüpunkt klicken. Wie Systemstatusansicht ist SystemStatusView und Inbox-Ansicht ist InboxView.

Mein Code funktioniert gut (es ändert die Ansicht in Rahmen und ändern Sie auch die Header-Beschriftung), wenn ich nicht verwenden. Aber ich möchte HamburgerMenu.ContentTemplate verwenden, um mit HamburgerMenu zu arbeiten.

Danke!

+1

Sie müssen genauer über ** was nicht funktioniert **. Welches Verhalten siehst du, wenn du 'ContentTemplate' verwendest? Ich habe Ihren Code so gut wie möglich reproduziert. Wenn ich auf einen Menüeintrag klicke, navigiert der Frame zum erwarteten Ansichtsmodell. –

Antwort

2

Wenn es funktioniert, wenn Sie nicht HamburgerMenu.ContentTemplate verwenden, aber nicht mehr funktioniert, wenn Sie dies tun, liegt das Problem wahrscheinlich darin, dass Sie die Standardvorlage so überschreiben, dass sie nicht alle Funktionen eines Steuerelements unterstützt.

Ich würde vorschlagen, dass Sie Blend verwenden, um den Standard HamburgerMenu.ContentTemplate zu erhalten, dann bearbeiten Sie es einfach nach Ihren Bedürfnissen, ohne zu viel zu ändern (beachten Sie, dass die Namen der als Vorlage verwendeten Steuerelemente eine entscheidende Bedeutung haben können, also Achte darauf, was du redigierst).

Wenn Sie nicht wissen, wie Sie Blend verwenden, um die Vorlage Ihrer Steuerung zu erhalten, hier ist ein einfaches Tutorial beschrieben in einer documentation of Telerik controls (keine Sorge, es funktioniert das gleiche für alle Steuerelemente). Sie müssen nur eine Kopie eines HamburgerMenu.ContentTemplate erstellen, fügen Sie es in Ihre Anwendung ein, und Sie sind gut zu gehen (Bearbeitung).