diff --git a/src/Cimbalino.Toolkit (UWP)/Cimbalino.Toolkit (UWP).csproj b/src/Cimbalino.Toolkit (UWP)/Cimbalino.Toolkit (UWP).csproj
index b9b1836..8a52d66 100644
--- a/src/Cimbalino.Toolkit (UWP)/Cimbalino.Toolkit (UWP).csproj
+++ b/src/Cimbalino.Toolkit (UWP)/Cimbalino.Toolkit (UWP).csproj
@@ -166,6 +166,9 @@
Controls\ExtendedPageBase.cs
+
+ Controls\IMasterDetailFrame.cs
+
Converters\BooleanToBrushConverter.cs
diff --git a/src/Cimbalino.Toolkit (WP8)/Cimbalino.Toolkit (WP8).csproj b/src/Cimbalino.Toolkit (WP8)/Cimbalino.Toolkit (WP8).csproj
index 9172d3b..969edd7 100644
--- a/src/Cimbalino.Toolkit (WP8)/Cimbalino.Toolkit (WP8).csproj
+++ b/src/Cimbalino.Toolkit (WP8)/Cimbalino.Toolkit (WP8).csproj
@@ -113,6 +113,7 @@
+
diff --git a/src/Cimbalino.Toolkit (WP8)/Controls/IMasterDetailFrame.cs b/src/Cimbalino.Toolkit (WP8)/Controls/IMasterDetailFrame.cs
new file mode 100644
index 0000000..97a94b8
--- /dev/null
+++ b/src/Cimbalino.Toolkit (WP8)/Controls/IMasterDetailFrame.cs
@@ -0,0 +1,28 @@
+// ****************************************************************************
+//
+// Copyright © Pedro Lamas 2014
+//
+// ****************************************************************************
+// Pedro Lamas
+// pedrolamas@gmail.com
+// Cimbalino.Toolkit
+// http://www.pedrolamas.com
+//
+// See license.txt in this solution or http://www.pedrolamas.com/license_MIT.txt
+//
+// ****************************************************************************
+
+namespace Cimbalino.Toolkit.Controls
+{
+ ///
+ /// Represents the basic operations for the MasterDetail control.
+ ///
+ public interface IMasterDetailFrame
+ {
+ ///
+ /// Called when the user presses the hardware back button.
+ ///
+ /// true if the back button press has been handled; otherwise, false.
+ bool HandleBackKeyPress();
+ }
+}
\ No newline at end of file
diff --git a/src/Cimbalino.Toolkit (WP8)/Services/NavigationService.cs b/src/Cimbalino.Toolkit (WP8)/Services/NavigationService.cs
index fec20c3..d093bea 100644
--- a/src/Cimbalino.Toolkit (WP8)/Services/NavigationService.cs
+++ b/src/Cimbalino.Toolkit (WP8)/Services/NavigationService.cs
@@ -143,6 +143,48 @@ public virtual bool Navigate(Type type, object parameter)
return ExceptionHelper.ThrowNotSupported();
}
+ ///
+ /// Navigates the detail frame to the content specified by the type reference.
+ ///
+ /// The page to navigate to, specified as a type reference to its partial class type.
+ /// true if navigation is not canceled; otherwise, false.
+ public bool NavigateDetail()
+ {
+ return ExceptionHelper.ThrowNotSupported();
+ }
+
+ ///
+ /// Navigates the detail frame to the content specified by the type reference.
+ ///
+ /// The page to navigate to, specified as a type reference to its partial class type.
+ /// The navigation parameter to pass to the target page; must have a basic type (string, char, numeric, or GUID).
+ /// true if navigation is not canceled; otherwise, false.
+ public bool NavigateDetail(object parameter)
+ {
+ return ExceptionHelper.ThrowNotSupported();
+ }
+
+ ///
+ /// Navigates the detail frame to the content specified by the type reference.
+ ///
+ /// The page to navigate to, specified as a type reference to its partial class type.
+ /// true if navigation is not canceled; otherwise, false.
+ public bool NavigateDetail(Type type)
+ {
+ return ExceptionHelper.ThrowNotSupported();
+ }
+
+ ///
+ /// Navigates the detail frame to the content specified by the type reference.
+ ///
+ /// The page to navigate to, specified as a type reference to its partial class type.
+ /// The navigation parameter to pass to the target page; must have a basic type (string, char, numeric, or GUID).
+ /// true if navigation is not canceled; otherwise, false.
+ public bool NavigateDetail(Type type, object parameter)
+ {
+ return ExceptionHelper.ThrowNotSupported();
+ }
+
///
/// Gets a value indicating whether there is at least one entry in back navigation history.
///
diff --git a/src/Cimbalino.Toolkit (WP81)/Cimbalino.Toolkit (WP81).csproj b/src/Cimbalino.Toolkit (WP81)/Cimbalino.Toolkit (WP81).csproj
index 28322d5..6b388b5 100644
--- a/src/Cimbalino.Toolkit (WP81)/Cimbalino.Toolkit (WP81).csproj
+++ b/src/Cimbalino.Toolkit (WP81)/Cimbalino.Toolkit (WP81).csproj
@@ -155,6 +155,9 @@
Controls\ExtendedPageBase.cs
+
+ Controls\IMasterDetailFrame.cs
+
Converters\BooleanToBrushConverter.cs
diff --git a/src/Cimbalino.Toolkit (WPA81)/Cimbalino.Toolkit (WPA81).csproj b/src/Cimbalino.Toolkit (WPA81)/Cimbalino.Toolkit (WPA81).csproj
index dfab1ea..5c57fd3 100644
--- a/src/Cimbalino.Toolkit (WPA81)/Cimbalino.Toolkit (WPA81).csproj
+++ b/src/Cimbalino.Toolkit (WPA81)/Cimbalino.Toolkit (WPA81).csproj
@@ -126,6 +126,9 @@
Controls\ExtendedPageBase.cs
+
+ Controls\IMasterDetailFrame.cs
+
Converters\BooleanToBrushConverter.cs
diff --git a/src/Cimbalino.Toolkit (WPA81)/Services/NavigationService.cs b/src/Cimbalino.Toolkit (WPA81)/Services/NavigationService.cs
index 84f2cbf..d36c2c6 100644
--- a/src/Cimbalino.Toolkit (WPA81)/Services/NavigationService.cs
+++ b/src/Cimbalino.Toolkit (WPA81)/Services/NavigationService.cs
@@ -15,6 +15,8 @@
#if WINDOWS_PHONE_APP
using System;
using System.Collections.Generic;
+using System.Linq;
+using Cimbalino.Toolkit.Controls;
using Cimbalino.Toolkit.Extensions;
using Cimbalino.Toolkit.Helpers;
using Windows.Phone.UI.Input;
@@ -23,6 +25,8 @@
#elif WINDOWS_UWP
using System;
using System.Collections.Generic;
+using System.Linq;
+using Cimbalino.Toolkit.Controls;
using Cimbalino.Toolkit.Extensions;
using Cimbalino.Toolkit.Helpers;
using Windows.Phone.UI.Input;
@@ -32,6 +36,7 @@
#else
using System;
using System.Collections.Generic;
+using System.Linq;
using Cimbalino.Toolkit.Extensions;
using Cimbalino.Toolkit.Helpers;
using Windows.UI.Xaml;
@@ -204,6 +209,48 @@ public virtual bool Navigate(Type type, object parameter)
return GetFrame()?.Navigate(type, parameter) ?? false;
}
+ ///
+ /// Navigates the detail frame to the content specified by the type reference.
+ ///
+ /// The page to navigate to, specified as a type reference to its partial class type.
+ /// true if navigation is not canceled; otherwise, false.
+ public bool NavigateDetail()
+ {
+ return Navigate(typeof(T));
+ }
+
+ ///
+ /// Navigates the detail frame to the content specified by the type reference.
+ ///
+ /// The page to navigate to, specified as a type reference to its partial class type.
+ /// The navigation parameter to pass to the target page; must have a basic type (string, char, numeric, or GUID).
+ /// true if navigation is not canceled; otherwise, false.
+ public bool NavigateDetail(object parameter)
+ {
+ return Navigate(typeof(T), parameter);
+ }
+
+ ///
+ /// Navigates the detail frame to the content specified by the type reference.
+ ///
+ /// The page to navigate to, specified as a type reference to its partial class type.
+ /// true if navigation is not canceled; otherwise, false.
+ public bool NavigateDetail(Type type)
+ {
+ return GetDetailFrame()?.Navigate(type) ?? false;
+ }
+
+ ///
+ /// Navigates the detail frame to the content specified by the type reference.
+ ///
+ /// The page to navigate to, specified as a type reference to its partial class type.
+ /// The navigation parameter to pass to the target page; must have a basic type (string, char, numeric, or GUID).
+ /// true if navigation is not canceled; otherwise, false.
+ public bool NavigateDetail(Type type, object parameter)
+ {
+ return GetDetailFrame()?.Navigate(type, parameter) ?? false;
+ }
+
///
/// Gets a value indicating whether there is at least one entry in back navigation history.
///
@@ -332,6 +379,20 @@ private Frame GetFrame()
return frame;
}
+ private Frame GetDetailFrame()
+ {
+ var detailFrame = (Frame)null;
+
+ var page = GetFrame()?.Content as Page;
+
+ if (page != null)
+ {
+ detailFrame = page.GetVisualDescendents().FirstOrDefault();
+ }
+
+ return detailFrame;
+ }
+
private void Frame_Navigated(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
CurrentParameter = e.Parameter;
@@ -386,38 +447,57 @@ private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
private bool HandleBackKeyPress()
{
- var handled = false;
+ var handled = (GetDetailFrame() as IMasterDetailFrame)?.HandleBackKeyPress() ?? false;
- var eventArgs = new NavigationServiceBackKeyPressedEventArgs();
+ if (!handled)
+ {
+ var eventArgs = new NavigationServiceBackKeyPressedEventArgs();
- RaiseBackKeyPressed(eventArgs);
+ RaiseBackKeyPressed(eventArgs);
- switch (eventArgs.Behavior)
- {
- case NavigationServiceBackKeyPressedBehavior.GoBack:
- var frame = GetFrame();
+ switch (eventArgs.Behavior)
+ {
+ case NavigationServiceBackKeyPressedBehavior.GoBack:
+ var frame = GetFrame();
+
+ if (frame?.CanGoBack ?? false)
+ {
+ frame.GoBack();
+ handled = true;
+ }
+ break;
- if (frame?.CanGoBack ?? false)
- {
- frame.GoBack();
+ case NavigationServiceBackKeyPressedBehavior.HideApp:
+ break;
+
+ case NavigationServiceBackKeyPressedBehavior.ExitApp:
handled = true;
- }
- break;
+ Application.Current?.Exit();
+ break;
+
+ case NavigationServiceBackKeyPressedBehavior.DoNothing:
+ handled = true;
+ break;
+
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
- case NavigationServiceBackKeyPressedBehavior.HideApp:
- break;
+ return handled;
+ }
- case NavigationServiceBackKeyPressedBehavior.ExitApp:
- handled = true;
- Application.Current?.Exit();
- break;
+ private bool HandleDetailBackKeyPress()
+ {
+ var handled = false;
+
+ var detailFrame = GetDetailFrame();
- case NavigationServiceBackKeyPressedBehavior.DoNothing:
- handled = true;
- break;
+ if (detailFrame != null && detailFrame.CanGoBack)
+ {
+ detailFrame.GoBack();
- default:
- throw new ArgumentOutOfRangeException();
+ handled = true;
}
return handled;
diff --git a/src/Cimbalino.Toolkit (Win81)/Cimbalino.Toolkit (Win81).csproj b/src/Cimbalino.Toolkit (Win81)/Cimbalino.Toolkit (Win81).csproj
index ddf51cb..05dc131 100644
--- a/src/Cimbalino.Toolkit (Win81)/Cimbalino.Toolkit (Win81).csproj
+++ b/src/Cimbalino.Toolkit (Win81)/Cimbalino.Toolkit (Win81).csproj
@@ -150,6 +150,9 @@
Controls\ExtendedPageBase.cs
+
+ Controls\IMasterDetailFrame.cs
+
Converters\BooleanToBrushConverter.cs
diff --git a/src/Cimbalino.Toolkit.Controls (UWP)/Cimbalino.Toolkit.Controls (UWP).csproj b/src/Cimbalino.Toolkit.Controls (UWP)/Cimbalino.Toolkit.Controls (UWP).csproj
index 62df8f2..a43d91b 100644
--- a/src/Cimbalino.Toolkit.Controls (UWP)/Cimbalino.Toolkit.Controls (UWP).csproj
+++ b/src/Cimbalino.Toolkit.Controls (UWP)/Cimbalino.Toolkit.Controls (UWP).csproj
@@ -127,6 +127,8 @@
+
+
diff --git a/src/Cimbalino.Toolkit.Controls (UWP)/Controls/HamburgerMenuButton.cs b/src/Cimbalino.Toolkit.Controls (UWP)/Controls/HamburgerMenuButton.cs
index ea0ee98..ab431cd 100644
--- a/src/Cimbalino.Toolkit.Controls (UWP)/Controls/HamburgerMenuButton.cs
+++ b/src/Cimbalino.Toolkit.Controls (UWP)/Controls/HamburgerMenuButton.cs
@@ -79,7 +79,7 @@ public Type NavigationSourcePageType
/// The navigation parameter property
///
public static readonly DependencyProperty NavigationParameterProperty = DependencyProperty.Register(
- nameof(NavigationParameter), typeof(object), typeof(HamburgerMenuButton), new PropertyMetadata(default(object)));
+ nameof(NavigationParameter), typeof(object), typeof(HamburgerMenuButton), new PropertyMetadata(null));
///
/// Gets or sets the navigation parameter.
diff --git a/src/Cimbalino.Toolkit.Controls (UWP)/Controls/HamburgerTitleBar.cs b/src/Cimbalino.Toolkit.Controls (UWP)/Controls/HamburgerTitleBar.cs
index 3545e7c..416ce15 100644
--- a/src/Cimbalino.Toolkit.Controls (UWP)/Controls/HamburgerTitleBar.cs
+++ b/src/Cimbalino.Toolkit.Controls (UWP)/Controls/HamburgerTitleBar.cs
@@ -89,7 +89,7 @@ protected override void OnApplyTemplate()
base.OnApplyTemplate();
- _menuButton = (Button)GetTemplateChild("MenuButton");
+ _menuButton = (Button)this.GetTemplateChild("MenuButton");
if (_menuButton != null)
{
diff --git a/src/Cimbalino.Toolkit.Controls (UWP)/Controls/MasterDetailFrame.cs b/src/Cimbalino.Toolkit.Controls (UWP)/Controls/MasterDetailFrame.cs
new file mode 100644
index 0000000..b9c9e6a
--- /dev/null
+++ b/src/Cimbalino.Toolkit.Controls (UWP)/Controls/MasterDetailFrame.cs
@@ -0,0 +1,173 @@
+// ****************************************************************************
+//
+// Copyright © Pedro Lamas 2014
+//
+// ****************************************************************************
+// Pedro Lamas
+// pedrolamas@gmail.com
+// Cimbalino.Toolkit.Controls
+// http://www.pedrolamas.com
+//
+// See license.txt in this solution or http://www.pedrolamas.com/license_MIT.txt
+//
+// ****************************************************************************
+
+using System;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Media;
+
+namespace Cimbalino.Toolkit.Controls
+{
+ ///
+ /// A master detail frame.
+ ///
+ [TemplateVisualState(Name = DisplayModeStatesName, GroupName = DefaultStateName)]
+ [TemplateVisualState(Name = DisplayModeStatesName, GroupName = CompactMasterStateName)]
+ public class MasterDetailFrame : Frame, IMasterDetailFrame
+ {
+ private const string DisplayModeStatesName = "DisplayModeStates";
+ private const string DefaultStateName = "Default";
+ private const string CompactMasterStateName = "CompactMaster";
+ private const string CompactDetailStateName = "CompactDetail";
+
+ ///
+ /// Gets or sets the master.
+ ///
+ /// The master.
+ public UIElement Master
+ {
+ get { return (UIElement)GetValue(MasterProperty); }
+ set { SetValue(MasterProperty, value); }
+ }
+
+ ///
+ /// Identifier for the dependency property.
+ ///
+ public static readonly DependencyProperty MasterProperty =
+ DependencyProperty.Register(nameof(Master), typeof(UIElement), typeof(MasterDetailFrame), new PropertyMetadata(null));
+
+ ///
+ /// Gets or sets the background of the master.
+ ///
+ /// The background of the master.
+ public Brush MasterBackground
+ {
+ get { return (Brush)GetValue(MasterBackgroundProperty); }
+ set { SetValue(MasterBackgroundProperty, value); }
+ }
+
+ ///
+ /// Identifier for the dependency property.
+ ///
+ public static readonly DependencyProperty MasterBackgroundProperty =
+ DependencyProperty.Register(nameof(MasterBackground), typeof(Brush), typeof(MasterDetailFrame), new PropertyMetadata(null));
+
+ ///
+ /// Gets or sets the width of the master.
+ ///
+ /// The width of the master.
+ public double MasterLength
+ {
+ get { return (double)GetValue(MasterLengthProperty); }
+ set { SetValue(MasterLengthProperty, value); }
+ }
+
+ ///
+ /// Identifier for the dependency property.
+ ///
+ public static readonly DependencyProperty MasterLengthProperty =
+ DependencyProperty.Register(nameof(MasterLength), typeof(double), typeof(MasterDetailFrame), new PropertyMetadata(0));
+
+ ///
+ /// Gets or sets the display mode.
+ ///
+ /// The display mode.
+ public MasterDetailFrameDisplayMode DisplayMode
+ {
+ get { return (MasterDetailFrameDisplayMode)GetValue(DisplayModeProperty); }
+ set { SetValue(DisplayModeProperty, value); }
+ }
+
+ ///
+ /// Identifier for the dependency property.
+ ///
+ public static readonly DependencyProperty DisplayModeProperty =
+ DependencyProperty.Register(nameof(DisplayMode), typeof(MasterDetailFrameDisplayMode), typeof(MasterDetailFrame), new PropertyMetadata(MasterDetailFrameDisplayMode.Normal, OnDisplayModeChanged));
+
+ private static void OnDisplayModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ var masterDetailFrame = (MasterDetailFrame)d;
+
+ masterDetailFrame.Update();
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MasterDetailFrame()
+ {
+ DefaultStyleKey = typeof(MasterDetailFrame);
+
+ if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
+ {
+ return;
+ }
+
+ this.Navigated += MasterDetailFrame_Navigated;
+
+ this.Navigate(typeof(Page));
+ }
+
+ ///
+ /// When overridden in a derived class, is invoked whenever application code or internal processes call ApplyTemplate.
+ ///
+ protected override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ Update();
+ }
+
+ private void Update()
+ {
+ switch (DisplayMode)
+ {
+ case MasterDetailFrameDisplayMode.Normal:
+ VisualStateManager.GoToState(this, DefaultStateName, true);
+ break;
+
+ case MasterDetailFrameDisplayMode.Compact:
+ VisualStateManager.GoToState(this, this.CanGoBack ? CompactDetailStateName : CompactMasterStateName, true);
+ break;
+
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ private void MasterDetailFrame_Navigated(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
+ {
+ while (this.BackStackDepth > 1)
+ {
+ this.BackStack.RemoveAt(this.BackStackDepth - 1);
+ }
+
+ Update();
+ }
+
+ bool IMasterDetailFrame.HandleBackKeyPress()
+ {
+ var handled = false;
+
+ if (DisplayMode == MasterDetailFrameDisplayMode.Compact && this.CanGoBack)
+ {
+ this.GoBack();
+
+ handled = true;
+ }
+
+ return handled;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Cimbalino.Toolkit.Controls (UWP)/Controls/MasterDetailFrameDisplayMode.cs b/src/Cimbalino.Toolkit.Controls (UWP)/Controls/MasterDetailFrameDisplayMode.cs
new file mode 100644
index 0000000..464021a
--- /dev/null
+++ b/src/Cimbalino.Toolkit.Controls (UWP)/Controls/MasterDetailFrameDisplayMode.cs
@@ -0,0 +1,32 @@
+// ****************************************************************************
+//
+// Copyright © Pedro Lamas 2014
+//
+// ****************************************************************************
+// Pedro Lamas
+// pedrolamas@gmail.com
+// Cimbalino.Toolkit
+// http://www.pedrolamas.com
+//
+// See license.txt in this solution or http://www.pedrolamas.com/license_MIT.txt
+//
+// ****************************************************************************
+
+namespace Cimbalino.Toolkit.Controls
+{
+ ///
+ /// Represents the display mode.
+ ///
+ public enum MasterDetailFrameDisplayMode
+ {
+ ///
+ /// Normal display mode.
+ ///
+ Normal,
+
+ ///
+ /// Compact display mode.
+ ///
+ Compact
+ }
+}
\ No newline at end of file
diff --git a/src/Cimbalino.Toolkit.Controls (UWP)/Themes/Generic.xaml b/src/Cimbalino.Toolkit.Controls (UWP)/Themes/Generic.xaml
index b6dfb5b..f40f451 100644
--- a/src/Cimbalino.Toolkit.Controls (UWP)/Themes/Generic.xaml
+++ b/src/Cimbalino.Toolkit.Controls (UWP)/Themes/Generic.xaml
@@ -37,6 +37,14 @@
+
@@ -69,15 +77,6 @@
-
-
@@ -96,6 +95,20 @@
+
+
+
+
+
+
@@ -187,20 +200,6 @@
-
-
-
-
-
-
@@ -257,40 +256,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -336,6 +301,105 @@
Padding="{TemplateBinding Padding}" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+