From 3831017d8fe2cb9b085009ee5a22c676694e8213 Mon Sep 17 00:00:00 2001 From: "E.Z. Hart" Date: Fri, 27 Jan 2017 17:14:21 -0700 Subject: Make WinRT/UWP platform classes more maintainable (#652) * Split Platform.cs into partial classes * Split the NavigationPageRenderer into partial classes for easier maintenance * Simplify GetCommandBarAsync, remove unneeded comments * Correct broken GetCommandBarAsync method * Fix OSX build --- .../NavigationPageRendererUWP.cs | 97 +++++ Xamarin.Forms.Platform.UAP/PlatformUWP.cs | 257 ++++++++++++ .../Xamarin.Forms.Platform.UAP.csproj | 2 + .../NavigationPageRenderer.cs | 146 +------ .../NavigationPageRendererWinRT.cs | 57 +++ Xamarin.Forms.Platform.WinRT/Platform.cs | 461 ++------------------- Xamarin.Forms.Platform.WinRT/PlatformWinRT.cs | 211 ++++++++++ .../Xamarin.Forms.Platform.WinRT.csproj | 4 +- 8 files changed, 677 insertions(+), 558 deletions(-) create mode 100644 Xamarin.Forms.Platform.UAP/NavigationPageRendererUWP.cs create mode 100644 Xamarin.Forms.Platform.UAP/PlatformUWP.cs create mode 100644 Xamarin.Forms.Platform.WinRT/NavigationPageRendererWinRT.cs create mode 100644 Xamarin.Forms.Platform.WinRT/PlatformWinRT.cs diff --git a/Xamarin.Forms.Platform.UAP/NavigationPageRendererUWP.cs b/Xamarin.Forms.Platform.UAP/NavigationPageRendererUWP.cs new file mode 100644 index 00000000..a56ce903 --- /dev/null +++ b/Xamarin.Forms.Platform.UAP/NavigationPageRendererUWP.cs @@ -0,0 +1,97 @@ +using Windows.UI.Core; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Data; +using Xamarin.Forms.PlatformConfiguration.WindowsSpecific; + +namespace Xamarin.Forms.Platform.UWP +{ + public partial class NavigationPageRenderer : IToolBarForegroundBinder + { + SystemNavigationManager _navManager; + + public void BindForegroundColor(AppBar appBar) + { + SetAppBarForegroundBinding(appBar); + } + + public void BindForegroundColor(AppBarButton button) + { + SetAppBarForegroundBinding(button); + } + + void SetAppBarForegroundBinding(FrameworkElement element) + { + element.SetBinding(Control.ForegroundProperty, + new Windows.UI.Xaml.Data.Binding { Path = new PropertyPath("TitleBrush"), Source = _container, RelativeSource = new RelativeSource { Mode = RelativeSourceMode.TemplatedParent } }); + } + + void UpdateToolbarPlacement() + { + if (_container == null) + { + return; + } + + _container.ToolbarPlacement = Element.OnThisPlatform().GetToolbarPlacement(); + } + + void UpdateShowTitle() + { + ((ITitleProvider)this).ShowTitle = _parentTabbedPage == null && _parentMasterDetailPage == null; + } + + static object GetDefaultColor() + { + return Windows.UI.Xaml.Application.Current.Resources["SystemControlBackgroundChromeMediumLowBrush"]; + } + + void UpdateBackButton() + { + bool showBackButton = PageController.InternalChildren.Count > 1 && NavigationPage.GetHasBackButton(_currentPage); + _container.ShowBackButton = showBackButton; + + if (_navManager != null) + { + _navManager.AppViewBackButtonVisibility = showBackButton ? AppViewBackButtonVisibility.Visible : AppViewBackButtonVisibility.Collapsed; + } + } + + async void UpdateTitleOnParents() + { + if (Element == null) + return; + + ITitleProvider render = null; + if (_parentTabbedPage != null) + { + render = Platform.GetRenderer(_parentTabbedPage) as ITitleProvider; + if (render != null) + render.ShowTitle = (_parentTabbedPage.CurrentPage == Element) && NavigationPage.GetHasNavigationBar(_currentPage); + } + + if (_parentMasterDetailPage != null) + { + render = Platform.GetRenderer(_parentMasterDetailPage) as ITitleProvider; + if (render != null) + render.ShowTitle = (_parentMasterDetailPage.Detail == Element) && NavigationPage.GetHasNavigationBar(_currentPage); + } + + if (render != null && render.ShowTitle) + { + render.Title = _currentPage.Title; + render.BarBackgroundBrush = GetBarBackgroundBrush(); + render.BarForegroundBrush = GetBarForegroundBrush(); + } + + if (_showTitle || (render != null && render.ShowTitle)) + { + var platform = Element.Platform as Platform; + if (platform != null) + { + await platform.UpdateToolbarItems(); + } + } + } + } +} diff --git a/Xamarin.Forms.Platform.UAP/PlatformUWP.cs b/Xamarin.Forms.Platform.UAP/PlatformUWP.cs new file mode 100644 index 00000000..83cb9129 --- /dev/null +++ b/Xamarin.Forms.Platform.UAP/PlatformUWP.cs @@ -0,0 +1,257 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Windows.ApplicationModel.Core; +using Windows.Foundation; +using Windows.Foundation.Metadata; +using Windows.UI; +using Windows.UI.Core; +using Windows.UI.ViewManagement; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace Xamarin.Forms.Platform.UWP +{ + public abstract partial class Platform + { + internal static StatusBar MobileStatusBar => ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar") ? StatusBar.GetForCurrentView() : null; + + IToolbarProvider _toolbarProvider; + + void InitializeStatusBar() + { + StatusBar statusBar = MobileStatusBar; + if (statusBar != null) + { + statusBar.Showing += (sender, args) => UpdateBounds(); + statusBar.Hiding += (sender, args) => UpdateBounds(); + + // UWP 14393 Bug: If RequestedTheme is Light (which it is by default), then the + // status bar uses White Foreground with White Background. + // UWP 10586 Bug: If RequestedTheme is Light (which it is by default), then the + // status bar uses Black Foreground with Black Background. + // Since the Light theme should have a Black on White status bar, we will set it explicitly. + // This can be overriden by setting the status bar colors in App.xaml.cs OnLaunched. + + if (statusBar.BackgroundColor == null && statusBar.ForegroundColor == null && Windows.UI.Xaml.Application.Current.RequestedTheme == ApplicationTheme.Light) + { + statusBar.BackgroundColor = Colors.White; + statusBar.ForegroundColor = Colors.Black; + statusBar.BackgroundOpacity = 1; + } + } + } + + void UpdateToolbarTitle(Page page) + { + if (_toolbarProvider == null) + return; + + ((ToolbarProvider)_toolbarProvider).CommandBar.Content = page.Title; + } + + async void OnPageActionSheet(Page sender, ActionSheetArguments options) + { + List buttons = options.Buttons.ToList(); + + var list = new Windows.UI.Xaml.Controls.ListView + { + Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["ActionSheetList"], + ItemsSource = buttons, + IsItemClickEnabled = true + }; + + var dialog = new ContentDialog + { + Template = (Windows.UI.Xaml.Controls.ControlTemplate)Windows.UI.Xaml.Application.Current.Resources["MyContentDialogControlTemplate"], + Content = list, + Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["ActionSheetStyle"] + }; + + if (options.Title != null) + dialog.Title = options.Title; + + list.ItemClick += (s, e) => + { + dialog.Hide(); + options.SetResult((string)e.ClickedItem); + }; + + TypedEventHandler onEscapeButtonPressed = delegate (CoreWindow window, CharacterReceivedEventArgs args) + { + if (args.KeyCode == 27) + { + dialog.Hide(); + options.SetResult(ContentDialogResult.None.ToString()); + } + }; + + Window.Current.CoreWindow.CharacterReceived += onEscapeButtonPressed; + + _actionSheetOptions = options; + + if (options.Cancel != null) + dialog.SecondaryButtonText = options.Cancel; + + if (options.Destruction != null) + dialog.PrimaryButtonText = options.Destruction; + + ContentDialogResult result = await dialog.ShowAsync(); + if (result == ContentDialogResult.Secondary) + options.SetResult(options.Cancel); + else if (result == ContentDialogResult.Primary) + options.SetResult(options.Destruction); + + Window.Current.CoreWindow.CharacterReceived -= onEscapeButtonPressed; + } + + void ClearCommandBar() + { + if (_toolbarProvider != null) + { + _toolbarProvider = null; + if (Device.Idiom == TargetIdiom.Phone) + _page.BottomAppBar = null; + else + _page.TopAppBar = null; + } + } + + CommandBar CreateCommandBar() + { + var bar = new FormsCommandBar(); + if (Device.Idiom != TargetIdiom.Phone) + bar.Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["TitleToolbar"]; + + _toolbarProvider = new ToolbarProvider(bar); + + if (Device.Idiom == TargetIdiom.Phone) + _page.BottomAppBar = bar; + else + _page.TopAppBar = bar; + + return bar; + } + + async Task GetCommandBarAsync() + { + IToolbarProvider provider = GetToolbarProvider(); + if (provider == null) + { + return null; + } + + return await provider.GetCommandBarAsync(); + } + + void UpdateBounds() + { + _bounds = new Rectangle(0, 0, _page.ActualWidth, _page.ActualHeight); + + StatusBar statusBar = MobileStatusBar; + if (statusBar != null) + { + bool landscape = Device.Info.CurrentOrientation.IsLandscape(); + bool titleBar = CoreApplication.GetCurrentView().TitleBar.IsVisible; + double offset = landscape ? statusBar.OccludedRect.Width : statusBar.OccludedRect.Height; + + _bounds = new Rectangle(0, 0, _page.ActualWidth - (landscape ? offset : 0), _page.ActualHeight - (landscape ? 0 : offset)); + + // Even if the MainPage is a ContentPage not inside of a NavigationPage, the calculated bounds + // assume the TitleBar is there even if it isn't visible. When UpdatePageSizes is called, + // _container.ActualWidth is correct because it's aware that the TitleBar isn't there, but the + // bounds aren't, and things can subsequently run under the StatusBar. + if (!titleBar) + { + _bounds.Width -= (_bounds.Width - _container.ActualWidth); + } + } + } + + internal async Task UpdateToolbarItems() + { + CommandBar commandBar = await GetCommandBarAsync(); + if (commandBar != null) + { + commandBar.PrimaryCommands.Clear(); + commandBar.SecondaryCommands.Clear(); + + if (_page.BottomAppBar != null || _page.TopAppBar != null) + { + _page.BottomAppBar = null; + _page.TopAppBar = null; + _page.InvalidateMeasure(); + } + } + + var toolBarProvider = GetToolbarProvider() as IToolBarForegroundBinder; + + foreach (ToolbarItem item in _toolbarTracker.ToolbarItems.OrderBy(ti => ti.Priority)) + { + if (commandBar == null) + commandBar = CreateCommandBar(); + + toolBarProvider?.BindForegroundColor(commandBar); + + var button = new AppBarButton(); + button.SetBinding(AppBarButton.LabelProperty, "Text"); + button.SetBinding(AppBarButton.IconProperty, "Icon", _fileImageSourcePathConverter); + button.Command = new MenuItemCommand(item); + button.DataContext = item; + + ToolbarItemOrder order = item.Order == ToolbarItemOrder.Default ? ToolbarItemOrder.Primary : item.Order; + if (order == ToolbarItemOrder.Primary) + { + toolBarProvider?.BindForegroundColor(button); + commandBar.PrimaryCommands.Add(button); + } + else + { + commandBar.SecondaryCommands.Add(button); + } + } + + if (commandBar?.PrimaryCommands.Count + commandBar?.SecondaryCommands.Count == 0) + ClearCommandBar(); + } + + internal IToolbarProvider GetToolbarProvider() + { + IToolbarProvider provider = null; + + Page element = _currentPage; + while (element != null) + { + provider = GetRenderer(element) as IToolbarProvider; + if (provider != null) + break; + + var pageContainer = element as IPageContainer; + element = pageContainer?.CurrentPage; + } + + if (provider != null && _toolbarProvider == null) + ClearCommandBar(); + + return provider; + } + + class ToolbarProvider : IToolbarProvider + { + readonly Task _commandBar; + + public ToolbarProvider(CommandBar commandBar) + { + _commandBar = Task.FromResult(commandBar); + } + + public CommandBar CommandBar => _commandBar.Result; + + public Task GetCommandBarAsync() + { + return _commandBar; + } + } + } +} diff --git a/Xamarin.Forms.Platform.UAP/Xamarin.Forms.Platform.UAP.csproj b/Xamarin.Forms.Platform.UAP/Xamarin.Forms.Platform.UAP.csproj index 66ab6023..ec7bca5a 100644 --- a/Xamarin.Forms.Platform.UAP/Xamarin.Forms.Platform.UAP.csproj +++ b/Xamarin.Forms.Platform.UAP/Xamarin.Forms.Platform.UAP.csproj @@ -192,6 +192,8 @@ + + TextAlignmentToHorizontalAlignmentConverter.cs diff --git a/Xamarin.Forms.Platform.WinRT/NavigationPageRenderer.cs b/Xamarin.Forms.Platform.WinRT/NavigationPageRenderer.cs index d5da8cdc..e7e01843 100644 --- a/Xamarin.Forms.Platform.WinRT/NavigationPageRenderer.cs +++ b/Xamarin.Forms.Platform.WinRT/NavigationPageRenderer.cs @@ -13,35 +13,23 @@ using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Animation; using Xamarin.Forms.Internals; -using Xamarin.Forms.PlatformConfiguration.WindowsSpecific; #if WINDOWS_UWP -using Windows.UI.Xaml.Data; using Windows.UI.Core; - -#endif - -#if WINDOWS_UWP - namespace Xamarin.Forms.Platform.UWP #else namespace Xamarin.Forms.Platform.WinRT #endif { - public class NavigationPageRenderer : IVisualElementRenderer, ITitleProvider, IToolbarProvider -#if WINDOWS_UWP - , IToolBarForegroundBinder -#endif + public partial class NavigationPageRenderer : IVisualElementRenderer, ITitleProvider, IToolbarProvider { PageControl _container; Page _currentPage; Page _previousPage; bool _disposed; -#if WINDOWS_UWP - SystemNavigationManager _navManager; -#endif + MasterDetailPage _parentMasterDetailPage; TabbedPage _parentTabbedPage; bool _showTitle = true; @@ -152,7 +140,7 @@ namespace Xamarin.Forms.Platform.WinRT public void SetElement(VisualElement element) { if (element != null && !(element is NavigationPage)) - throw new ArgumentException("Element must be a Page", "element"); + throw new ArgumentException("Element must be a Page", nameof(element)); NavigationPage oldElement = Element; Element = (NavigationPage)element; @@ -213,8 +201,11 @@ namespace Xamarin.Forms.Platform.WinRT protected void Dispose(bool disposing) { - if (!disposing || _disposed) + if (_disposed || !disposing) + { return; + } + PageController?.SendDisappearing(); _disposed = true; @@ -249,11 +240,8 @@ namespace Xamarin.Forms.Platform.WinRT Brush GetBarBackgroundBrush() { -#if WINDOWS_UWP - object defaultColor = Windows.UI.Xaml.Application.Current.Resources["SystemControlBackgroundChromeMediumLowBrush"]; -#else - object defaultColor = Windows.UI.Xaml.Application.Current.Resources["ApplicationPageBackgroundThemeBrush"]; -#endif + object defaultColor = GetDefaultColor(); + if (Element.BarBackgroundColor.IsDefault && defaultColor != null) return (Brush)defaultColor; return Element.BarBackgroundColor.ToBrush(); @@ -267,28 +255,11 @@ namespace Xamarin.Forms.Platform.WinRT return Element.BarTextColor.ToBrush(); } - // TODO EZH Why don't this and GetToolBarProvider ever get called on either platform? - Task GetCommandBarAsync() - { - var platform = (Platform)Element.Platform; - IToolbarProvider toolbarProvider = platform.GetToolbarProvider(); - if (toolbarProvider == null) - return Task.FromResult(null); - - return toolbarProvider.GetCommandBarAsync(); - } - bool GetIsNavBarPossible() { return _showTitle; } - IToolbarProvider GetToolbarProvider() - { - var platform = (Platform)Element.Platform; - return platform.GetToolbarProvider(); - } - void LookupRelevantParents() { IEnumerable parentPages = Element.GetParentPages(); @@ -308,16 +279,9 @@ namespace Xamarin.Forms.Platform.WinRT _parentTabbedPage.PropertyChanged += MultiPagePropertyChanged; if (_parentMasterDetailPage != null) _parentMasterDetailPage.PropertyChanged += MultiPagePropertyChanged; -#if WINDOWS_UWP - ((ITitleProvider)this).ShowTitle = _parentTabbedPage == null && _parentMasterDetailPage == null; - -#else - if (Device.Idiom == TargetIdiom.Phone && _parentTabbedPage != null) - ((ITitleProvider)this).ShowTitle = false; - else - ((ITitleProvider)this).ShowTitle = true; -#endif + UpdateShowTitle(); + UpdateTitleOnParents(); } @@ -355,8 +319,10 @@ namespace Xamarin.Forms.Platform.WinRT UpdateNavigationBarBackground(); else if (e.PropertyName == Page.PaddingProperty.PropertyName) UpdatePadding(); - else if (e.PropertyName == PlatformConfiguration.WindowsSpecific.Page.ToolbarPlacementProperty.PropertyName) +#if WINDOWS_UWP + else if (e.PropertyName == PlatformConfiguration.WindowsSpecific.Page.ToolbarPlacementProperty.PropertyName) UpdateToolbarPlacement(); +#endif } void OnLoaded(object sender, RoutedEventArgs args) @@ -470,19 +436,6 @@ namespace Xamarin.Forms.Platform.WinRT _container.DataContext = page; } - void UpdateBackButton() - { - bool showBackButton = PageController.InternalChildren.Count > 1 && NavigationPage.GetHasBackButton(_currentPage); - _container.ShowBackButton = showBackButton; - -#if WINDOWS_UWP - if (_navManager != null) - { - _navManager.AppViewBackButtonVisibility = showBackButton ? AppViewBackButtonVisibility.Visible : AppViewBackButtonVisibility.Collapsed; - } -#endif - } - void UpdateBackButtonTitle() { string title = null; @@ -527,74 +480,5 @@ namespace Xamarin.Forms.Platform.WinRT { (this as ITitleProvider).BarForegroundBrush = GetBarForegroundBrush(); } - - void UpdateToolbarPlacement() - { -#if WINDOWS_UWP - if (_container == null) - { - return; - } - - _container.ToolbarPlacement = Element.OnThisPlatform().GetToolbarPlacement(); -#endif - } - -#pragma warning disable 1998 // considered for removal - async void UpdateTitleOnParents() -#pragma warning restore 1998 - { - if (Element == null) - return; - - ITitleProvider render = null; - if (_parentTabbedPage != null) - { - render = Platform.GetRenderer(_parentTabbedPage) as ITitleProvider; - if (render != null) - render.ShowTitle = (_parentTabbedPage.CurrentPage == Element) && NavigationPage.GetHasNavigationBar(_currentPage); - } - - if (_parentMasterDetailPage != null) - { - render = Platform.GetRenderer(_parentMasterDetailPage) as ITitleProvider; - if (render != null) - render.ShowTitle = (_parentMasterDetailPage.Detail == Element) && NavigationPage.GetHasNavigationBar(_currentPage); - } - - if (render != null && render.ShowTitle) - { - render.Title = _currentPage.Title; - render.BarBackgroundBrush = GetBarBackgroundBrush(); - render.BarForegroundBrush = GetBarForegroundBrush(); -#if WINDOWS_UWP - await (Element.Platform as Platform).UpdateToolbarItems(); -#endif - } - else if (_showTitle) - { -#if WINDOWS_UWP - await (Element.Platform as Platform).UpdateToolbarItems(); -#endif - } - } - -#if WINDOWS_UWP - public void BindForegroundColor(AppBar appBar) - { - SetAppBarForegroundBinding(appBar); - } - - public void BindForegroundColor(AppBarButton button) - { - SetAppBarForegroundBinding(button); - } - - void SetAppBarForegroundBinding(FrameworkElement element) - { - element.SetBinding(Control.ForegroundProperty, - new Windows.UI.Xaml.Data.Binding { Path = new PropertyPath("TitleBrush"), Source = _container, RelativeSource = new RelativeSource { Mode = RelativeSourceMode.TemplatedParent } }); - } -#endif } -} \ No newline at end of file +} diff --git a/Xamarin.Forms.Platform.WinRT/NavigationPageRendererWinRT.cs b/Xamarin.Forms.Platform.WinRT/NavigationPageRendererWinRT.cs new file mode 100644 index 00000000..1539d3aa --- /dev/null +++ b/Xamarin.Forms.Platform.WinRT/NavigationPageRendererWinRT.cs @@ -0,0 +1,57 @@ +namespace Xamarin.Forms.Platform.WinRT +{ + public partial class NavigationPageRenderer + { + void UpdateShowTitle() + { + if (Device.Idiom == TargetIdiom.Phone && _parentTabbedPage != null) + ((ITitleProvider)this).ShowTitle = false; + else + ((ITitleProvider)this).ShowTitle = true; + } + + static object GetDefaultColor() + { + return Windows.UI.Xaml.Application.Current.Resources["ApplicationPageBackgroundThemeBrush"]; + } + + void UpdateBackButton() + { + bool showBackButton = PageController.InternalChildren.Count > 1 && NavigationPage.GetHasBackButton(_currentPage); + _container.ShowBackButton = showBackButton; + } + + void UpdateToolbarPlacement() + { + // Currently we don't support toolbar (CommandBar) placement on Windows 8.1 + } + + void UpdateTitleOnParents() + { + if (Element == null) + return; + + ITitleProvider render = null; + if (_parentTabbedPage != null) + { + render = Platform.GetRenderer(_parentTabbedPage) as ITitleProvider; + if (render != null) + render.ShowTitle = (_parentTabbedPage.CurrentPage == Element) && NavigationPage.GetHasNavigationBar(_currentPage); + } + + if (_parentMasterDetailPage != null) + { + render = Platform.GetRenderer(_parentMasterDetailPage) as ITitleProvider; + if (render != null) + render.ShowTitle = (_parentMasterDetailPage.Detail == Element) && NavigationPage.GetHasNavigationBar(_currentPage); + } + + if (render != null && render.ShowTitle) + { + render.Title = _currentPage.Title; + render.BarBackgroundBrush = GetBarBackgroundBrush(); + render.BarForegroundBrush = GetBarForegroundBrush(); + } + } + } +} diff --git a/Xamarin.Forms.Platform.WinRT/Platform.cs b/Xamarin.Forms.Platform.WinRT/Platform.cs index 2e30ac10..ec356e9a 100644 --- a/Xamarin.Forms.Platform.WinRT/Platform.cs +++ b/Xamarin.Forms.Platform.WinRT/Platform.cs @@ -2,39 +2,22 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; - -using Windows.ApplicationModel.Core; -using Windows.UI; using Windows.UI.Popups; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Media.Animation; using Xamarin.Forms.Internals; #if WINDOWS_UWP -using Windows.Foundation; -using Windows.Foundation.Metadata; -using Windows.UI.Core; -using Windows.UI.ViewManagement; -#endif - -#if WINDOWS_UWP - namespace Xamarin.Forms.Platform.UWP #else - namespace Xamarin.Forms.Platform.WinRT #endif { - public abstract class Platform : IPlatform, INavigation, IToolbarProvider + public abstract partial class Platform : IPlatform, INavigation, IToolbarProvider { - internal static readonly BindableProperty RendererProperty = BindableProperty.CreateAttached("Renderer", typeof(IVisualElementRenderer), typeof(Platform), default(IVisualElementRenderer)); - -#if WINDOWS_UWP - internal static StatusBar MobileStatusBar => ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar") ? StatusBar.GetForCurrentView() : null; -#endif + internal static readonly BindableProperty RendererProperty = BindableProperty.CreateAttached("Renderer", + typeof(IVisualElementRenderer), typeof(Platform), default(IVisualElementRenderer)); public static IVisualElementRenderer GetRenderer(VisualElement element) { @@ -50,9 +33,10 @@ namespace Xamarin.Forms.Platform.WinRT public static IVisualElementRenderer CreateRenderer(VisualElement element) { if (element == null) - throw new ArgumentNullException("element"); + throw new ArgumentNullException(nameof(element)); - IVisualElementRenderer renderer = Registrar.Registered.GetHandler(element.GetType()) ?? new DefaultRenderer(); + IVisualElementRenderer renderer = Registrar.Registered.GetHandler(element.GetType()) ?? + new DefaultRenderer(); renderer.SetElement(element); return renderer; } @@ -60,11 +44,14 @@ namespace Xamarin.Forms.Platform.WinRT internal Platform(Windows.UI.Xaml.Controls.Page page) { if (page == null) - throw new ArgumentNullException("page"); + throw new ArgumentNullException(nameof(page)); _page = page; - _container = new Canvas { Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["RootContainerStyle"] }; + _container = new Canvas + { + Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["RootContainerStyle"] + }; _page.Content = _container; @@ -84,38 +71,19 @@ namespace Xamarin.Forms.Platform.WinRT UpdateBounds(); #if WINDOWS_UWP - StatusBar statusBar = MobileStatusBar; - if (statusBar != null) - { - statusBar.Showing += (sender, args) => UpdateBounds(); - statusBar.Hiding += (sender, args) => UpdateBounds(); - - // UWP 14393 Bug: If RequestedTheme is Light (which it is by default), then the - // status bar uses White Foreground with White Background. - // UWP 10586 Bug: If RequestedTheme is Light (which it is by default), then the - // status bar uses Black Foreground with Black Background. - // Since the Light theme should have a Black on White status bar, we will set it explicitly. - // This can be overriden by setting the status bar colors in App.xaml.cs OnLaunched. - - if (statusBar.BackgroundColor == null && statusBar.ForegroundColor == null && Windows.UI.Xaml.Application.Current.RequestedTheme == ApplicationTheme.Light) - { - statusBar.BackgroundColor = Colors.White; - statusBar.ForegroundColor = Colors.Black; - statusBar.BackgroundOpacity = 1; - } - } + InitializeStatusBar(); #endif } internal void SetPage(Page newRoot) { if (newRoot == null) - throw new ArgumentNullException("newRoot"); + throw new ArgumentNullException(nameof(newRoot)); _navModel.Clear(); _navModel.Push(newRoot, null); - SetCurrent(newRoot, false, true); + SetCurrent(newRoot, true); Application.Current.NavigationProxy.Inner = this; } @@ -156,7 +124,8 @@ namespace Xamarin.Forms.Platform.WinRT Task INavigation.PopToRootAsync(bool animated) { - throw new InvalidOperationException("PopToRootAsync is not supported globally on Windows, please use a NavigationPage."); + throw new InvalidOperationException( + "PopToRootAsync is not supported globally on Windows, please use a NavigationPage."); } void INavigation.RemovePage(Page page) @@ -166,7 +135,8 @@ namespace Xamarin.Forms.Platform.WinRT void INavigation.InsertPageBefore(Page page, Page before) { - throw new InvalidOperationException("InsertPageBefore is not supported globally on Windows, please use a NavigationPage."); + throw new InvalidOperationException( + "InsertPageBefore is not supported globally on Windows, please use a NavigationPage."); } Task INavigation.PushModalAsync(Page page) @@ -182,11 +152,11 @@ namespace Xamarin.Forms.Platform.WinRT Task INavigation.PushModalAsync(Page page, bool animated) { if (page == null) - throw new ArgumentNullException("page"); + throw new ArgumentNullException(nameof(page)); var tcs = new TaskCompletionSource(); _navModel.PushModal(page); - SetCurrent(page, animated, completedCallback: () => tcs.SetResult(true)); + SetCurrent(page, completedCallback: () => tcs.SetResult(true)); return tcs.Task; } @@ -194,7 +164,7 @@ namespace Xamarin.Forms.Platform.WinRT { var tcs = new TaskCompletionSource(); Page result = _navModel.PopModal(); - SetCurrent(_navModel.CurrentPage, animated, true, () => tcs.SetResult(result)); + SetCurrent(_navModel.CurrentPage, true, () => tcs.SetResult(result)); return tcs.Task; } @@ -235,128 +205,6 @@ namespace Xamarin.Forms.Platform.WinRT } } - internal IToolbarProvider GetToolbarProvider() - { - IToolbarProvider provider = null; - - Page element = _currentPage; - while (element != null) - { - provider = GetRenderer(element) as IToolbarProvider; - if (provider != null) - break; - - var pageContainer = element as IPageContainer; - element = pageContainer?.CurrentPage; - } - - if (provider != null && _toolbarProvider == null) - ClearCommandBar(); - - return provider; - } - - internal async Task UpdateToolbarItems() - { - CommandBar commandBar = await GetCommandBarAsync(); - if (commandBar != null) - { - commandBar.PrimaryCommands.Clear(); - commandBar.SecondaryCommands.Clear(); -#if WINDOWS_UWP - if (_page.BottomAppBar != null || _page.TopAppBar != null) - { - _page.BottomAppBar = null; - _page.TopAppBar = null; - _page.InvalidateMeasure(); - } -#endif - } - -#if !WINDOWS_UWP - commandBar = AddOpenMasterButton(commandBar); -#endif - -#if WINDOWS_UWP - var toolBarProvider = GetToolbarProvider() as IToolBarForegroundBinder; -#endif - - foreach (ToolbarItem item in _toolbarTracker.ToolbarItems.OrderBy(ti => ti.Priority)) - { - if (commandBar == null) - commandBar = CreateCommandBar(); - -#if WINDOWS_UWP - toolBarProvider?.BindForegroundColor(commandBar); -#endif - - var button = new AppBarButton(); - button.SetBinding(AppBarButton.LabelProperty, "Text"); - button.SetBinding(AppBarButton.IconProperty, "Icon", _fileImageSourcePathConverter); - button.Command = new MenuItemCommand(item); - button.DataContext = item; - - - ToolbarItemOrder order = item.Order == ToolbarItemOrder.Default ? ToolbarItemOrder.Primary : item.Order; - - if (order == ToolbarItemOrder.Primary) - { -#if WINDOWS_UWP - toolBarProvider?.BindForegroundColor(button); -#endif - commandBar.PrimaryCommands.Add(button); - } - else - commandBar.SecondaryCommands.Add(button); - } - - if (commandBar?.PrimaryCommands.Count + commandBar?.SecondaryCommands.Count == 0) - ClearCommandBar(); - } - -#if !WINDOWS_UWP - CommandBar AddOpenMasterButton(CommandBar commandBar) - { - if (!_toolbarTracker.HaveMasterDetail) - { - return commandBar; - } - - if (commandBar == null) - { - commandBar = CreateCommandBar(); - } - - Page target = _toolbarTracker.Target; - var mdp = target as MasterDetailPage; - while (mdp == null) - { - var container = target as IPageContainer; - if (container == null) - { - break; - } - - target = container.CurrentPage; - mdp = container.CurrentPage as MasterDetailPage; - } - - if (mdp == null || !mdp.ShouldShowToolbarButton()) - { - return commandBar; - } - - var openMaster = new AppBarButton { DataContext = mdp }; - openMaster.SetBinding(AppBarButton.LabelProperty, "Master.Title"); - openMaster.SetBinding(AppBarButton.IconProperty, "Master.Icon", _fileImageSourcePathConverter); - openMaster.Click += (s, a) => { mdp.IsPresented = !mdp.IsPresented; }; - - commandBar.PrimaryCommands.Add(openMaster); - - return commandBar; - } -#endif - Rectangle _bounds; readonly Canvas _container; readonly Windows.UI.Xaml.Controls.Page _page; @@ -366,32 +214,17 @@ namespace Xamarin.Forms.Platform.WinRT readonly ToolbarTracker _toolbarTracker = new ToolbarTracker(); readonly FileImageSourcePathConverter _fileImageSourcePathConverter = new FileImageSourcePathConverter(); -#pragma warning disable 649 - IToolbarProvider _toolbarProvider; -#pragma warning restore 649 - - class ToolbarProvider : IToolbarProvider - { - readonly Task _commandBar; - - public ToolbarProvider(CommandBar commandBar) - { - _commandBar = Task.FromResult(commandBar); - } - - public CommandBar CommandBar => _commandBar.Result; - - public Task GetCommandBarAsync() - { - return _commandBar; - } - } Windows.UI.Xaml.Controls.ProgressBar GetBusyIndicator() { if (_busyIndicator == null) { - _busyIndicator = new Windows.UI.Xaml.Controls.ProgressBar { IsIndeterminate = true, Visibility = Visibility.Collapsed, VerticalAlignment = VerticalAlignment.Top }; + _busyIndicator = new Windows.UI.Xaml.Controls.ProgressBar + { + IsIndeterminate = true, + Visibility = Visibility.Collapsed, + VerticalAlignment = VerticalAlignment.Top + }; Canvas.SetZIndex(_busyIndicator, 1); _container.Children.Add(_busyIndicator); @@ -417,7 +250,7 @@ namespace Xamarin.Forms.Platform.WinRT Page removed = _navModel.PopModal(); if (removed != null) { - SetCurrent(_navModel.CurrentPage, true, true); + SetCurrent(_navModel.CurrentPage, true); handled = true; } } @@ -436,18 +269,13 @@ namespace Xamarin.Forms.Platform.WinRT _currentActionSheet = null; } - void UpdateBounds() - { - _bounds = new Rectangle(0, 0, _container.ActualWidth, _container.ActualHeight); - } - void OnRendererSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs) { UpdateBounds(); UpdatePageSizes(); } - async void SetCurrent(Page newPage, bool animated, bool popping = false, Action completedCallback = null) + async void SetCurrent(Page newPage, bool popping = false, Action completedCallback = null) { if (newPage == _currentPage) return; @@ -472,84 +300,22 @@ namespace Xamarin.Forms.Platform.WinRT pageRenderer.ContainerElement.Width = _container.ActualWidth; pageRenderer.ContainerElement.Height = _container.ActualHeight; - if (completedCallback != null) - completedCallback(); + completedCallback?.Invoke(); _currentPage = newPage; UpdateToolbarTracker(); +#if WINDOWS_UWP UpdateToolbarTitle(newPage); +#endif await UpdateToolbarItems(); } - void UpdateToolbarTitle(Page page) - { - if (_toolbarProvider == null) - return; - - ((ToolbarProvider)_toolbarProvider).CommandBar.Content = page.Title; - } - Task IToolbarProvider.GetCommandBarAsync() { return GetCommandBarAsync(); } -#pragma warning disable 1998 // considered for removal - async Task GetCommandBarAsync() -#pragma warning restore 1998 - { -#if !WINDOWS_UWP - return _page.BottomAppBar as CommandBar; -#else - IToolbarProvider provider = GetToolbarProvider(); - //var titleProvider = provider as ITitleProvider; - if (provider == null) // || (titleProvider != null && !titleProvider.ShowTitle)) - return null; - - return await provider.GetCommandBarAsync(); -#endif - } - - CommandBar CreateCommandBar() - { -#if !WINDOWS_UWP - var commandBar = new CommandBar(); - _page.BottomAppBar = commandBar; - return commandBar; -#else - - var bar = new FormsCommandBar(); - if (Device.Idiom != TargetIdiom.Phone) - bar.Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["TitleToolbar"]; - - _toolbarProvider = new ToolbarProvider(bar); - - if (Device.Idiom == TargetIdiom.Phone) - _page.BottomAppBar = bar; - else - _page.TopAppBar = bar; - - return bar; -#endif - } - - void ClearCommandBar() - { -#if !WINDOWS_UWP - _page.BottomAppBar = null; -#else - if (_toolbarProvider != null) - { - _toolbarProvider = null; - if (Device.Idiom == TargetIdiom.Phone) - _page.BottomAppBar = null; - else - _page.TopAppBar = null; - } -#endif - } - async void OnToolbarItemsChanged(object sender, EventArgs e) { await UpdateToolbarItems(); @@ -565,163 +331,6 @@ namespace Xamarin.Forms.Platform.WinRT ActionSheetArguments _actionSheetOptions; Popup _currentActionSheet; -#if WINDOWS_UWP - async void OnPageActionSheet(Page sender, ActionSheetArguments options) - { - List buttons = options.Buttons.ToList(); - - var list = new Windows.UI.Xaml.Controls.ListView - { - Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["ActionSheetList"], - ItemsSource = buttons, - IsItemClickEnabled = true - }; - - var dialog = new ContentDialog - { - Template = (Windows.UI.Xaml.Controls.ControlTemplate)Windows.UI.Xaml.Application.Current.Resources["MyContentDialogControlTemplate"], - Content = list, - Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["ActionSheetStyle"] - }; - - if (options.Title != null) - dialog.Title = options.Title; - - list.ItemClick += (s, e) => - { - dialog.Hide(); - options.SetResult((string)e.ClickedItem); - }; - - TypedEventHandler onEscapeButtonPressed = delegate(CoreWindow window, CharacterReceivedEventArgs args) - { - if (args.KeyCode == 27) - { - dialog.Hide(); - options.SetResult(ContentDialogResult.None.ToString()); - } - }; - - Window.Current.CoreWindow.CharacterReceived += onEscapeButtonPressed; - - _actionSheetOptions = options; - - if (options.Cancel != null) - dialog.SecondaryButtonText = options.Cancel; - - if (options.Destruction != null) - dialog.PrimaryButtonText = options.Destruction; - - ContentDialogResult result = await dialog.ShowAsync(); - if (result == ContentDialogResult.Secondary) - options.SetResult(options.Cancel); - else if (result == ContentDialogResult.Primary) - options.SetResult(options.Destruction); - - Window.Current.CoreWindow.CharacterReceived -= onEscapeButtonPressed; - } -#else - void OnPageActionSheet(Page sender, ActionSheetArguments options) - { - var finalArguments = new List(); - if (options.Destruction != null) - finalArguments.Add(options.Destruction); - if (options.Buttons != null) - finalArguments.AddRange(options.Buttons); - if (options.Cancel != null) - finalArguments.Add(options.Cancel); - - var list = new Windows.UI.Xaml.Controls.ListView - { - Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["ActionSheetList"], - ItemsSource = finalArguments, - IsItemClickEnabled = true - }; - - list.ItemClick += (s, e) => - { - _currentActionSheet.IsOpen = false; - options.SetResult((string)e.ClickedItem); - }; - - _actionSheetOptions = options; - - Size size = Device.Info.ScaledScreenSize; - - var stack = new StackPanel - { - MinWidth = 100, - Children = - { - new TextBlock - { - Text = options.Title ?? string.Empty, - Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["TitleTextBlockStyle"], - Margin = new Windows.UI.Xaml.Thickness(0, 0, 0, 10), - Visibility = options.Title != null ? Visibility.Visible : Visibility.Collapsed - }, - list - } - }; - - var border = new Border - { - Child = stack, - BorderBrush = new SolidColorBrush(Colors.White), - BorderThickness = new Windows.UI.Xaml.Thickness(1), - Padding = new Windows.UI.Xaml.Thickness(15), - Background = (Brush)Windows.UI.Xaml.Application.Current.Resources["AppBarBackgroundThemeBrush"] - }; - - Windows.UI.Xaml.Controls.Grid.SetRow(border, 1); - Windows.UI.Xaml.Controls.Grid.SetColumn(border, 1); - - var container = new Windows.UI.Xaml.Controls.Grid - { - RowDefinitions = - { - new Windows.UI.Xaml.Controls.RowDefinition { Height = new Windows.UI.Xaml.GridLength(1, Windows.UI.Xaml.GridUnitType.Star) }, - new Windows.UI.Xaml.Controls.RowDefinition { Height = new Windows.UI.Xaml.GridLength(0, Windows.UI.Xaml.GridUnitType.Auto) }, - new Windows.UI.Xaml.Controls.RowDefinition { Height = new Windows.UI.Xaml.GridLength(1, Windows.UI.Xaml.GridUnitType.Star) } - }, - ColumnDefinitions = - { - new Windows.UI.Xaml.Controls.ColumnDefinition { Width = new Windows.UI.Xaml.GridLength(1, Windows.UI.Xaml.GridUnitType.Star) }, - new Windows.UI.Xaml.Controls.ColumnDefinition { Width = new Windows.UI.Xaml.GridLength(0, Windows.UI.Xaml.GridUnitType.Auto) }, - new Windows.UI.Xaml.Controls.ColumnDefinition { Width = new Windows.UI.Xaml.GridLength(1, Windows.UI.Xaml.GridUnitType.Star) } - }, - Height = size.Height, - Width = size.Width, - Children = { border } - }; - - var bgPopup = new Popup { Child = new Canvas { Width = size.Width, Height = size.Height, Background = new SolidColorBrush(new Windows.UI.Color { A = 128, R = 0, G = 0, B = 0 }) } }; - - bgPopup.IsOpen = true; - - _currentActionSheet = new Popup { ChildTransitions = new TransitionCollection { new PopupThemeTransition() }, IsLightDismissEnabled = true, Child = container }; - - _currentActionSheet.Closed += (s, e) => - { - bgPopup.IsOpen = false; - CancelActionSheet(); - }; - - if (Device.Idiom == TargetIdiom.Phone) - { - double height = _page.ActualHeight; - stack.Height = height; - stack.Width = size.Width; - border.BorderThickness = new Windows.UI.Xaml.Thickness(0); - - _currentActionSheet.Height = height; - _currentActionSheet.VerticalOffset = size.Height - height; - } - - _currentActionSheet.IsOpen = true; - } -#endif - async void OnPageAlert(Page sender, AlertArguments options) { string content = options.Message ?? options.Title ?? string.Empty; @@ -759,7 +368,7 @@ namespace Xamarin.Forms.Platform.WinRT } } } - + // refer to http://stackoverflow.com/questions/29209954/multiple-messagedialog-app-crash for why this is used // in order to allow for multiple MessageDialogs, or a crash occurs otherwise public static class MessageDialogExtensions @@ -773,8 +382,8 @@ namespace Xamarin.Forms.Platform.WinRT await _currentDialogShowRequest.Task; } - var request = _currentDialogShowRequest = new TaskCompletionSource(); - var result = await dialog.ShowAsync(); + TaskCompletionSource request = _currentDialogShowRequest = new TaskCompletionSource(); + IUICommand result = await dialog.ShowAsync(); _currentDialogShowRequest = null; request.SetResult(dialog); diff --git a/Xamarin.Forms.Platform.WinRT/PlatformWinRT.cs b/Xamarin.Forms.Platform.WinRT/PlatformWinRT.cs new file mode 100644 index 00000000..5e11c8d8 --- /dev/null +++ b/Xamarin.Forms.Platform.WinRT/PlatformWinRT.cs @@ -0,0 +1,211 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Windows.UI; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Media.Animation; + +namespace Xamarin.Forms.Platform.WinRT +{ + public abstract partial class Platform + { + CommandBar AddOpenMasterButton(CommandBar commandBar) + { + if (!_toolbarTracker.HaveMasterDetail) + { + return commandBar; + } + + if (commandBar == null) + { + commandBar = CreateCommandBar(); + } + + Page target = _toolbarTracker.Target; + var mdp = target as MasterDetailPage; + while (mdp == null) + { + var container = target as IPageContainer; + if (container == null) + { + break; + } + + target = container.CurrentPage; + mdp = container.CurrentPage as MasterDetailPage; + } + + if (mdp == null || !mdp.ShouldShowToolbarButton()) + { + return commandBar; + } + + var openMaster = new AppBarButton { DataContext = mdp }; + openMaster.SetBinding(AppBarButton.LabelProperty, "Master.Title"); + openMaster.SetBinding(AppBarButton.IconProperty, "Master.Icon", _fileImageSourcePathConverter); + openMaster.Click += (s, a) => { mdp.IsPresented = !mdp.IsPresented; }; + + commandBar.PrimaryCommands.Add(openMaster); + + return commandBar; + } + + CommandBar CreateCommandBar() + { + var commandBar = new CommandBar(); + _page.BottomAppBar = commandBar; + return commandBar; + } + + void UpdateBounds() + { + _bounds = new Rectangle(0, 0, _page.ActualWidth, _page.ActualHeight); + } + + Task GetCommandBarAsync() + { + return Task.FromResult(_page.BottomAppBar as CommandBar); + } + + void ClearCommandBar() + { + _page.BottomAppBar = null; + } + + void OnPageActionSheet(Page sender, ActionSheetArguments options) + { + var finalArguments = new List(); + if (options.Destruction != null) + finalArguments.Add(options.Destruction); + if (options.Buttons != null) + finalArguments.AddRange(options.Buttons); + if (options.Cancel != null) + finalArguments.Add(options.Cancel); + + var list = new Windows.UI.Xaml.Controls.ListView + { + Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["ActionSheetList"], + ItemsSource = finalArguments, + IsItemClickEnabled = true + }; + + list.ItemClick += (s, e) => + { + _currentActionSheet.IsOpen = false; + options.SetResult((string)e.ClickedItem); + }; + + _actionSheetOptions = options; + + Size size = Device.Info.ScaledScreenSize; + + var stack = new StackPanel + { + MinWidth = 100, + Children = + { + new TextBlock + { + Text = options.Title ?? string.Empty, + Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["TitleTextBlockStyle"], + Margin = new Windows.UI.Xaml.Thickness(0, 0, 0, 10), + Visibility = options.Title != null ? Visibility.Visible : Visibility.Collapsed + }, + list + } + }; + + var border = new Border + { + Child = stack, + BorderBrush = new SolidColorBrush(Colors.White), + BorderThickness = new Windows.UI.Xaml.Thickness(1), + Padding = new Windows.UI.Xaml.Thickness(15), + Background = (Brush)Windows.UI.Xaml.Application.Current.Resources["AppBarBackgroundThemeBrush"] + }; + + Windows.UI.Xaml.Controls.Grid.SetRow(border, 1); + Windows.UI.Xaml.Controls.Grid.SetColumn(border, 1); + + var container = new Windows.UI.Xaml.Controls.Grid + { + RowDefinitions = + { + new Windows.UI.Xaml.Controls.RowDefinition { Height = new Windows.UI.Xaml.GridLength(1, Windows.UI.Xaml.GridUnitType.Star) }, + new Windows.UI.Xaml.Controls.RowDefinition { Height = new Windows.UI.Xaml.GridLength(0, Windows.UI.Xaml.GridUnitType.Auto) }, + new Windows.UI.Xaml.Controls.RowDefinition { Height = new Windows.UI.Xaml.GridLength(1, Windows.UI.Xaml.GridUnitType.Star) } + }, + ColumnDefinitions = + { + new Windows.UI.Xaml.Controls.ColumnDefinition { Width = new Windows.UI.Xaml.GridLength(1, Windows.UI.Xaml.GridUnitType.Star) }, + new Windows.UI.Xaml.Controls.ColumnDefinition { Width = new Windows.UI.Xaml.GridLength(0, Windows.UI.Xaml.GridUnitType.Auto) }, + new Windows.UI.Xaml.Controls.ColumnDefinition { Width = new Windows.UI.Xaml.GridLength(1, Windows.UI.Xaml.GridUnitType.Star) } + }, + Height = size.Height, + Width = size.Width, + Children = { border } + }; + + var bgPopup = new Popup { Child = new Canvas { Width = size.Width, Height = size.Height, Background = new SolidColorBrush(new Windows.UI.Color { A = 128, R = 0, G = 0, B = 0 }) } }; + + bgPopup.IsOpen = true; + + _currentActionSheet = new Popup { ChildTransitions = new TransitionCollection { new PopupThemeTransition() }, IsLightDismissEnabled = true, Child = container }; + + _currentActionSheet.Closed += (s, e) => + { + bgPopup.IsOpen = false; + CancelActionSheet(); + }; + + if (Device.Idiom == TargetIdiom.Phone) + { + double height = _page.ActualHeight; + stack.Height = height; + stack.Width = size.Width; + border.BorderThickness = new Windows.UI.Xaml.Thickness(0); + + _currentActionSheet.Height = height; + _currentActionSheet.VerticalOffset = size.Height - height; + } + + _currentActionSheet.IsOpen = true; + } + + internal async Task UpdateToolbarItems() + { + CommandBar commandBar = await GetCommandBarAsync(); + if (commandBar != null) + { + commandBar.PrimaryCommands.Clear(); + commandBar.SecondaryCommands.Clear(); + } + + commandBar = AddOpenMasterButton(commandBar); + + foreach (ToolbarItem item in _toolbarTracker.ToolbarItems.OrderBy(ti => ti.Priority)) + { + if (commandBar == null) + commandBar = CreateCommandBar(); + + var button = new AppBarButton(); + button.SetBinding(AppBarButton.LabelProperty, "Text"); + button.SetBinding(AppBarButton.IconProperty, "Icon", _fileImageSourcePathConverter); + button.Command = new MenuItemCommand(item); + button.DataContext = item; + + ToolbarItemOrder order = item.Order == ToolbarItemOrder.Default ? ToolbarItemOrder.Primary : item.Order; + if (order == ToolbarItemOrder.Primary) + commandBar.PrimaryCommands.Add(button); + else + commandBar.SecondaryCommands.Add(button); + } + + if (commandBar?.PrimaryCommands.Count + commandBar?.SecondaryCommands.Count == 0) + ClearCommandBar(); + } + } +} diff --git a/Xamarin.Forms.Platform.WinRT/Xamarin.Forms.Platform.WinRT.csproj b/Xamarin.Forms.Platform.WinRT/Xamarin.Forms.Platform.WinRT.csproj index 22068d0b..766fd728 100644 --- a/Xamarin.Forms.Platform.WinRT/Xamarin.Forms.Platform.WinRT.csproj +++ b/Xamarin.Forms.Platform.WinRT/Xamarin.Forms.Platform.WinRT.csproj @@ -68,6 +68,8 @@ + + @@ -192,4 +194,4 @@ --> - + \ No newline at end of file -- cgit v1.2.3