2013-07-25 9 views
5

Hat jemand Glück gehabt, den MahApps.Metro-Stil auf ein NavigationWindow anzuwenden? Ich habe es für ein Fenster in Ordnung, aber muss es auf ein Navigationsfenster mit Seiten anwenden. Ich habe versucht, NavigationWindow zu erweitern und die Änderungen von MetroWindow so hinzuzufügen, aber kein Glück. Das Fenster hat eine Standardtitelleiste und einen Rahmen und der Inhalt ist komplett schwarz.Anwenden von MahApps.Metro style auf NavigationWindow

using System; 
using System.Windows; 
using System.Windows.Input; 
using System.Windows.Interop; 
using System.Windows.Media; 
using System.Windows.Navigation; 
using MahApps.Metro.Native; 

namespace MahApps.Metro.Controls 
{ 
    [TemplatePart(Name = PART_TitleBar, Type = typeof(UIElement))] 
    [TemplatePart(Name = PART_WindowCommands, Type = typeof(WindowCommands))] 
    public class MetroNavigationWindow : NavigationWindow 
    { 
     private const string PART_TitleBar = "PART_TitleBar"; 
     private const string PART_WindowCommands = "PART_WindowCommands"; 

     public static readonly DependencyProperty ShowIconOnTitleBarProperty = DependencyProperty.Register("ShowIconOnTitleBar", typeof(bool), typeof(MetroNavigationWindow), new PropertyMetadata(true)); 
     public static readonly DependencyProperty ShowTitleBarProperty = DependencyProperty.Register("ShowTitleBar", typeof(bool), typeof(MetroNavigationWindow), new PropertyMetadata(true)); 
     public static readonly DependencyProperty ShowMinButtonProperty = DependencyProperty.Register("ShowMinButton", typeof(bool), typeof(MetroNavigationWindow), new PropertyMetadata(true)); 
     public static readonly DependencyProperty ShowCloseButtonProperty = DependencyProperty.Register("ShowCloseButton", typeof(bool), typeof(MetroNavigationWindow), new PropertyMetadata(true)); 
     public static readonly DependencyProperty ShowMaxRestoreButtonProperty = DependencyProperty.Register("ShowMaxRestoreButton", typeof(bool), typeof(MetroNavigationWindow), new PropertyMetadata(true)); 
     public static readonly DependencyProperty TitlebarHeightProperty = DependencyProperty.Register("TitlebarHeight", typeof(int), typeof(MetroNavigationWindow), new PropertyMetadata(30)); 
     public static readonly DependencyProperty TitleCapsProperty = DependencyProperty.Register("TitleCaps", typeof(bool), typeof(MetroNavigationWindow), new PropertyMetadata(true)); 
     public static readonly DependencyProperty SaveWindowPositionProperty = DependencyProperty.Register("SaveWindowPosition", typeof(bool), typeof(MetroNavigationWindow), new PropertyMetadata(false)); 
     public static readonly DependencyProperty WindowPlacementSettingsProperty = DependencyProperty.Register("WindowPlacementSettings", typeof(IWindowPlacementSettings), typeof(MetroNavigationWindow), new PropertyMetadata(null)); 
     public static readonly DependencyProperty TitleForegroundProperty = DependencyProperty.Register("TitleForeground", typeof(Brush), typeof(MetroNavigationWindow)); 
     public static readonly DependencyProperty IgnoreTaskbarOnMaximizeProperty = DependencyProperty.Register("IgnoreTaskbarOnMaximize", typeof(bool), typeof(MetroNavigationWindow), new PropertyMetadata(false)); 
     public static readonly DependencyProperty GlowBrushProperty = DependencyProperty.Register("GlowBrush", typeof(SolidColorBrush), typeof(MetroNavigationWindow), new PropertyMetadata(null)); 
     public static readonly DependencyProperty FlyoutsProperty = DependencyProperty.Register("Flyouts", typeof(FlyoutsControl), typeof(MetroNavigationWindow), new PropertyMetadata(null)); 
     public static readonly DependencyProperty WindowTransitionsEnabledProperty = DependencyProperty.Register("WindowTransitionsEnabled", typeof(bool), typeof(MetroNavigationWindow), new PropertyMetadata(true)); 

     bool isDragging; 

     public bool WindowTransitionsEnabled 
     { 
      get { return (bool)this.GetValue(WindowTransitionsEnabledProperty); } 
      set { SetValue(WindowTransitionsEnabledProperty, value); } 
     } 

     public FlyoutsControl Flyouts 
     { 
      get { return (FlyoutsControl)GetValue(FlyoutsProperty); } 
      set { SetValue(FlyoutsProperty, value); } 
     } 

     public WindowCommands WindowCommands { get; set; } 

     public bool IgnoreTaskbarOnMaximize 
     { 
      get { return (bool)this.GetValue(IgnoreTaskbarOnMaximizeProperty); } 
      set { SetValue(IgnoreTaskbarOnMaximizeProperty, value); } 
     } 

     public Brush TitleForeground 
     { 
      get { return (Brush)GetValue(TitleForegroundProperty); } 
      set { SetValue(TitleForegroundProperty, value); } 
     } 

     public bool SaveWindowPosition 
     { 
      get { return (bool)GetValue(SaveWindowPositionProperty); } 
      set { SetValue(SaveWindowPositionProperty, value); } 
     } 

     public IWindowPlacementSettings WindowPlacementSettings 
     { 
      get { return (IWindowPlacementSettings)GetValue(WindowPlacementSettingsProperty); } 
      set { SetValue(WindowPlacementSettingsProperty, value); } 
     } 

     public bool ShowIconOnTitleBar 
     { 
      get { return (bool)GetValue(ShowIconOnTitleBarProperty); } 
      set { SetValue(ShowIconOnTitleBarProperty, value); } 
     } 

     public bool ShowTitleBar 
     { 
      get { return (bool)GetValue(ShowTitleBarProperty); } 
      set { SetValue(ShowTitleBarProperty, value); } 
     } 

     public bool ShowMinButton 
     { 
      get { return (bool)GetValue(ShowMinButtonProperty); } 
      set { SetValue(ShowMinButtonProperty, value); } 
     } 

     public bool ShowCloseButton 
     { 
      get { return (bool)GetValue(ShowCloseButtonProperty); } 
      set { SetValue(ShowCloseButtonProperty, value); } 
     } 

     public int TitlebarHeight 
     { 
      get { return (int)GetValue(TitlebarHeightProperty); } 
      set { SetValue(TitlebarHeightProperty, value); } 
     } 

     public bool ShowMaxRestoreButton 
     { 
      get { return (bool)GetValue(ShowMaxRestoreButtonProperty); } 
      set { SetValue(ShowMaxRestoreButtonProperty, value); } 
     } 

     public bool TitleCaps 
     { 
      get { return (bool)GetValue(TitleCapsProperty); } 
      set { SetValue(TitleCapsProperty, value); } 
     } 

     public SolidColorBrush GlowBrush 
     { 
      get { return (SolidColorBrush)GetValue(GlowBrushProperty); } 
      set { SetValue(GlowBrushProperty, value); } 
     } 

     public string WindowTitle 
     { 
      get { return TitleCaps ? Title.ToUpper() : Title; } 
     } 

     public MetroNavigationWindow() 
     { 
      Loaded += this.MetroWindow_Loaded; 
     } 

     private void MetroWindow_Loaded(object sender, RoutedEventArgs e) 
     { 
      VisualStateManager.GoToState(this, "AfterLoaded", true); 

      if (!ShowTitleBar) 
      { 
       //Disables the system menu for reasons other than clicking an invisible titlebar. 
       IntPtr handle = new WindowInteropHelper(this).Handle; 
       UnsafeNativeMethods.SetWindowLong(handle, UnsafeNativeMethods.GWL_STYLE, UnsafeNativeMethods.GetWindowLong(handle, UnsafeNativeMethods.GWL_STYLE) & ~UnsafeNativeMethods.WS_SYSMENU); 
      } 

      if (this.Flyouts == null) 
      { 
       this.Flyouts = new FlyoutsControl(); 
      } 
     } 

     static MetroNavigationWindow() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(MetroNavigationWindow), new FrameworkPropertyMetadata(typeof(MetroNavigationWindow))); 
     } 

     public override void OnApplyTemplate() 
     { 
      base.OnApplyTemplate(); 

      if (WindowCommands == null) 
       WindowCommands = new WindowCommands(); 

      var titleBar = GetTemplateChild(PART_TitleBar) as UIElement; 

      if (ShowTitleBar && titleBar != null) 
      { 
       titleBar.MouseDown += TitleBarMouseDown; 
       titleBar.MouseUp += TitleBarMouseUp; 
       titleBar.MouseMove += TitleBarMouseMove; 
      } 
      else 
      { 
       MouseDown += TitleBarMouseDown; 
       MouseUp += TitleBarMouseUp; 
       MouseMove += TitleBarMouseMove; 
      } 
     } 

     protected override void OnStateChanged(EventArgs e) 
     { 
      if (WindowCommands != null) 
      { 
       WindowCommands.RefreshMaximiseIconState(); 
      } 

      base.OnStateChanged(e); 
     } 

     protected void TitleBarMouseDown(object sender, MouseButtonEventArgs e) 
     { 
      var mousePosition = e.GetPosition(this); 
      bool isIconClick = ShowIconOnTitleBar && mousePosition.X <= TitlebarHeight && mousePosition.Y <= TitlebarHeight; 

      if (e.ChangedButton == MouseButton.Left) 
      { 
       if (isIconClick) 
       { 
        if (e.ClickCount == 2) 
        { 
         Close(); 
        } 
        else 
        { 
         ShowSystemMenuPhysicalCoordinates(this, PointToScreen(new Point(0, TitlebarHeight))); 
        } 
       } 
       else 
       { 
        IntPtr windowHandle = new WindowInteropHelper(this).Handle; 
        UnsafeNativeMethods.ReleaseCapture(); 

        var wpfPoint = PointToScreen(Mouse.GetPosition(this)); 
        short x = Convert.ToInt16(wpfPoint.X); 
        short y = Convert.ToInt16(wpfPoint.Y); 

        int lParam = x | (y << 16); 

        UnsafeNativeMethods.SendMessage(windowHandle, Constants.WM_NCLBUTTONDOWN, Constants.HT_CAPTION, lParam); 
        if (e.ClickCount == 2 && (ResizeMode == ResizeMode.CanResizeWithGrip || ResizeMode == ResizeMode.CanResize)) 
        { 
         WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized; 
        } 
       } 
      } 
      else if (e.ChangedButton == MouseButton.Right) 
      { 
       ShowSystemMenuPhysicalCoordinates(this, PointToScreen(mousePosition)); 
      } 
     } 

     protected void TitleBarMouseUp(object sender, MouseButtonEventArgs e) 
     { 
      isDragging = false; 
     } 

     private void TitleBarMouseMove(object sender, MouseEventArgs e) 
     { 
      if (e.LeftButton != MouseButtonState.Pressed) 
      { 
       isDragging = false; 
      } 

      if (isDragging 
       && WindowState == WindowState.Maximized 
       && ResizeMode != ResizeMode.NoResize) 
      { 
       // Calculating correct left coordinate for multi-screen system. 
       Point mouseAbsolute = PointToScreen(Mouse.GetPosition(this)); 
       double width = RestoreBounds.Width; 
       double left = mouseAbsolute.X - width/2; 

       // Check if the mouse is at the top of the screen if TitleBar is not visible 
       if (!ShowTitleBar && mouseAbsolute.Y > TitlebarHeight) 
        return; 

       // Aligning window's position to fit the screen. 
       double virtualScreenWidth = SystemParameters.VirtualScreenWidth; 
       left = left + width > virtualScreenWidth ? virtualScreenWidth - width : left; 

       var mousePosition = e.MouseDevice.GetPosition(this); 

       // When dragging the window down at the very top of the border, 
       // move the window a bit upwards to avoid showing the resize handle as soon as the mouse button is released 
       Top = mousePosition.Y < 5 ? -5 : mouseAbsolute.Y - mousePosition.Y; 
       Left = left; 

       // Restore window to normal state. 
       WindowState = WindowState.Normal; 
      } 
     } 

     internal T GetPart<T>(string name) where T : DependencyObject 
     { 
      return (T)GetTemplateChild(name); 
     } 

     private static void ShowSystemMenuPhysicalCoordinates(Window window, Point physicalScreenLocation) 
     { 
      if (window == null) return; 

      var hwnd = new WindowInteropHelper(window).Handle; 
      if (hwnd == IntPtr.Zero || !UnsafeNativeMethods.IsWindow(hwnd)) 
       return; 

      var hmenu = UnsafeNativeMethods.GetSystemMenu(hwnd, false); 

      var cmd = UnsafeNativeMethods.TrackPopupMenuEx(hmenu, Constants.TPM_LEFTBUTTON | Constants.TPM_RETURNCMD, (int)physicalScreenLocation.X, (int)physicalScreenLocation.Y, hwnd, IntPtr.Zero); 
      if (0 != cmd) 
       UnsafeNativeMethods.PostMessage(hwnd, Constants.SYSCOMMAND, new IntPtr(cmd), IntPtr.Zero); 
     } 
    } 
} 

Antwort

8

Um dies zu erreichen, ist mir ein MetroWindow als mein Haupt-Navigationsfenster und ein Frame innerhalb dieser MetroWindow, die die Navigation behandelt werden.

Navigationsfenster

<Controls:MetroWindow x:Class="TestWpfApplicationMahApps.Metro.NavWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
         xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" Title="NavWindow" Height="300" Width="300"> 
    <Window.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colours.xaml" /> 
       <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" /> 
       <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" /> 
       <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" /> 
       <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </Window.Resources> 
    <Frame Source="Page1.xaml" NavigationUIVisibility="Hidden"></Frame> 
</Controls:MetroWindow> 

Dies ermöglicht es mir nicht der Navigationslogik zu ändern, kann es von der NavigationService genannt werden wie es war, als ein NavigationWindow verwenden.

Page 1 CS-

/// <summary> 
/// Interaction logic for Page1.xaml 
/// </summary> 
public partial class Page1 : Page 
{ 
    public Page1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     NavigationService.Navigate(new Page2()); 
    } 
} 
+0

Ich hatte den Rahmen einen Namen also geben: BENN1TH

Verwandte Themen