diff options
author | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 13:02:25 -0700 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 16:13:41 -0700 |
commit | 17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch) | |
tree | b5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs | |
download | xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2 xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip |
Initial import
Diffstat (limited to 'Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs b/Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs new file mode 100644 index 00000000..6dfc1a47 --- /dev/null +++ b/Xamarin.Forms.Platform.UAP/TabbedPageRenderer.cs @@ -0,0 +1,264 @@ +using System; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Threading.Tasks; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Automation; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Media; + +namespace Xamarin.Forms.Platform.UWP +{ + internal class TabbedPagePresenter : Windows.UI.Xaml.Controls.ContentPresenter + { + public TabbedPagePresenter() + { + Loaded += TabbedPagePresenter_Loaded; + Unloaded += TabbedPagePresenter_Unloaded; + SizeChanged += (s, e) => + { + if (ActualWidth > 0 && ActualHeight > 0) + { + var tab = (Page)DataContext; + ((TabbedPage)tab.RealParent).ContainerArea = new Rectangle(0, 0, ActualWidth, ActualHeight); + } + }; + } + + void TabbedPagePresenter_Loaded(object sender, RoutedEventArgs e) + { + var tab = (Page)DataContext; + tab.SendAppearing(); + } + + void TabbedPagePresenter_Unloaded(object sender, RoutedEventArgs e) + { + var tab = (Page)DataContext; + tab.SendDisappearing(); + } + } + + public class TabbedPageRenderer : IVisualElementRenderer, ITitleProvider, IToolbarProvider + { + bool _disposed; + bool _showTitle; + VisualElementTracker<Page, Pivot> _tracker; + + public Pivot Control { get; private set; } + + public TabbedPage Element { get; private set; } + + protected VisualElementTracker<Page, Pivot> Tracker + { + get { return _tracker; } + set + { + if (_tracker == value) + return; + + if (_tracker != null) + _tracker.Dispose(); + + _tracker = value; + } + } + + public void Dispose() + { + Dispose(true); + } + + Brush ITitleProvider.BarBackgroundBrush + { + set { (Control as FormsPivot).ToolbarBackground = value; } + } + + Brush ITitleProvider.BarForegroundBrush + { + set { (Control as FormsPivot).ToolbarForeground = value; } + } + + bool ITitleProvider.ShowTitle + { + get { return _showTitle; } + + set + { + if (_showTitle == value) + return; + _showTitle = value; + + UpdateBarVisibility(); + } + } + + string ITitleProvider.Title + { + get { return (string)Control?.Title; } + + set + { + if (Control != null && _showTitle) + Control.Title = value; + } + } + + public Task<CommandBar> GetCommandBarAsync() + { + return (Control as IToolbarProvider)?.GetCommandBarAsync(); + } + + public FrameworkElement ContainerElement + { + get { return Control; } + } + + VisualElement IVisualElementRenderer.Element + { + get { return Element; } + } + + public event EventHandler<VisualElementChangedEventArgs> ElementChanged; + + public SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) + { + var constraint = new Windows.Foundation.Size(widthConstraint, heightConstraint); + + double oldWidth = Control.Width; + double oldHeight = Control.Height; + + Control.Height = double.NaN; + Control.Width = double.NaN; + + Control.Measure(constraint); + var result = new Size(Math.Ceiling(Control.DesiredSize.Width), Math.Ceiling(Control.DesiredSize.Height)); + + Control.Width = oldWidth; + Control.Height = oldHeight; + + return new SizeRequest(result); + } + + public void SetElement(VisualElement element) + { + if (element != null && !(element is TabbedPage)) + throw new ArgumentException("Element must be a TabbedPage", "element"); + + TabbedPage oldElement = Element; + Element = (TabbedPage)element; + + if (oldElement != null) + { + oldElement.PropertyChanged -= OnElementPropertyChanged; + ((INotifyCollectionChanged)oldElement.Children).CollectionChanged -= OnPagesChanged; + } + + if (element != null) + { + if (Control == null) + { + Control = new FormsPivot { Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["TabbedPageStyle"] }; + + Control.SelectionChanged += OnSelectionChanged; + + Tracker = new BackgroundTracker<Pivot>(Windows.UI.Xaml.Controls.Control.BackgroundProperty) { Element = (Page)element, Control = Control, Container = Control }; + + Control.Loaded += OnLoaded; + Control.Unloaded += OnUnloaded; + } + + Control.DataContext = Element; + OnPagesChanged(Element.Children, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + UpdateCurrentPage(); + + ((INotifyCollectionChanged)Element.Children).CollectionChanged += OnPagesChanged; + element.PropertyChanged += OnElementPropertyChanged; + + if (!string.IsNullOrEmpty(element.AutomationId)) + Control.SetValue(AutomationProperties.AutomationIdProperty, element.AutomationId); + } + + OnElementChanged(new VisualElementChangedEventArgs(oldElement, element)); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposing || _disposed) + return; + + _disposed = true; + Element?.SendDisappearing(); + SetElement(null); + Tracker = null; + } + + protected void OnElementChanged(VisualElementChangedEventArgs e) + { + EventHandler<VisualElementChangedEventArgs> changed = ElementChanged; + if (changed != null) + changed(this, e); + } + + void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == "CurrentPage") + UpdateCurrentPage(); + } + + void OnLoaded(object sender, RoutedEventArgs args) + { + if (Element == null) + return; + + Element.SendAppearing(); + } + + void OnPagesChanged(object sender, NotifyCollectionChangedEventArgs e) + { + e.Apply(Element.Children, Control.Items); + + // Potential performance issue, UpdateLayout () is called for every page change + Control.UpdateLayout(); + } + + void OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (Element == null) + return; + + Page page = e.AddedItems.Count > 0 ? (Page)e.AddedItems[0] : null; + Page currentPage = Element.CurrentPage; + if (currentPage == page) + return; + currentPage?.SendDisappearing(); + Element.CurrentPage = page; + page?.SendAppearing(); + } + + void OnUnloaded(object sender, RoutedEventArgs args) + { + if (Element == null) + return; + + Element.SendDisappearing(); + } + + void UpdateBarVisibility() + { + (Control as FormsPivot).ToolbarVisibility = _showTitle ? Visibility.Visible : Visibility.Collapsed; + } + + void UpdateCurrentPage() + { + Page page = Element.CurrentPage; + + var nav = page as NavigationPage; + ((ITitleProvider)this).ShowTitle = nav != null; + + if (page == null) + return; + + Control.SelectedItem = page; + } + } +}
\ No newline at end of file |