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/MasterDetailPageRenderer.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/MasterDetailPageRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs b/Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs new file mode 100644 index 00000000..c8c09789 --- /dev/null +++ b/Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs @@ -0,0 +1,312 @@ +using System; +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.Data; +using Windows.UI.Xaml.Media; + +namespace Xamarin.Forms.Platform.UWP +{ + public class MasterDetailPageRenderer : IVisualElementRenderer, IToolbarProvider, ITitleProvider, IToolBarForegroundBinder + { + Page _master; + Page _detail; + bool _showTitle; + + VisualElementTracker<Page, FrameworkElement> _tracker; + + public MasterDetailControl Control { get; private set; } + + public MasterDetailPage Element { get; private set; } + + protected VisualElementTracker<Page, FrameworkElement> Tracker + { + get { return _tracker; } + set + { + if (_tracker == value) + return; + + if (_tracker != null) + _tracker.Dispose(); + + _tracker = value; + } + } + + public void Dispose() + { + ClearMaster(); + ClearDetail(); + + Tracker = null; + if (Element != null) + SetElement(null); + } + + Brush ITitleProvider.BarBackgroundBrush + { + set { Control.ToolbarBackground = value; } + } + + Brush ITitleProvider.BarForegroundBrush + { + set { Control.ToolbarForeground = value; } + } + + bool ITitleProvider.ShowTitle + { + get { return _showTitle; } + + set + { + if (_showTitle == value) + return; + _showTitle = value; + if (_showTitle) + Control.DetailTitleVisibility = Visibility.Visible; + else + Control.DetailTitleVisibility = Visibility.Collapsed; + } + } + + string ITitleProvider.Title + { + get { return Element?.Title; } + + set + { + if (Control != null) + Control.DetailTitle = value; + } + } + + Task<CommandBar> IToolbarProvider.GetCommandBarAsync() + { + return ((IToolbarProvider)Control)?.GetCommandBarAsync(); + } + + FrameworkElement IVisualElementRenderer.ContainerElement + { + get { return Control; } + } + + VisualElement IVisualElementRenderer.Element + { + get { return Element; } + } + + public event EventHandler<VisualElementChangedEventArgs> ElementChanged; + + public SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) + { + Size size = Device.Info.ScaledScreenSize; + return new SizeRequest(new Size(size.Width, size.Height)); + } + + public void SetElement(VisualElement element) + { + MasterDetailPage old = Element; + Element = (MasterDetailPage)element; + + if (element != old) + OnElementChanged(new ElementChangedEventArgs<MasterDetailPage>(old, Element)); + } + + protected virtual void OnElementChanged(ElementChangedEventArgs<MasterDetailPage> e) + { + if (e.OldElement != null) + e.OldElement.PropertyChanged -= OnElementPropertyChanged; + + if (e.NewElement != null) + { + if (Control == null) + { + Control = new MasterDetailControl(); + Control.Loaded += OnControlLoaded; + Control.Unloaded += OnControlUnlaoded; + Control.SizeChanged += OnNativeSizeChanged; + + Control.RegisterPropertyChangedCallback(MasterDetailControl.IsPaneOpenProperty, OnIsPaneOpenChanged); + + Tracker = new VisualElementTracker<Page, FrameworkElement> { Container = Control, Element = Element }; + } + + e.NewElement.PropertyChanged += OnElementPropertyChanged; + UpdateDetail(); + UpdateMaster(); + UpdateMode(); + UpdateIsPresented(); + + if (!string.IsNullOrEmpty(e.NewElement.AutomationId)) + Control.SetValue(AutomationProperties.AutomationIdProperty, e.NewElement.AutomationId); + } + } + + protected virtual void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == MasterDetailPage.IsPresentedProperty.PropertyName) + UpdateIsPresented(); + else if (e.PropertyName == "Master") + UpdateMaster(); + else if (e.PropertyName == "Detail") + UpdateDetail(); + else if (e.PropertyName == "ShouldShowSplitMode") + UpdateMode(); + } + + void ClearDetail() + { + ((ITitleProvider)this).ShowTitle = false; + + if (_detail == null) + return; + + _detail.PropertyChanged -= OnDetailPropertyChanged; + + IVisualElementRenderer renderer = Platform.GetRenderer(_detail); + renderer?.Dispose(); + + _detail.ClearValue(Platform.RendererProperty); + _detail = null; + } + + void ClearMaster() + { + if (_master == null) + return; + + _master.PropertyChanged -= OnMasterPropertyChanged; + + IVisualElementRenderer renderer = Platform.GetRenderer(_master); + renderer?.Dispose(); + + _master.ClearValue(Platform.RendererProperty); + _master = null; + } + + void OnControlLoaded(object sender, RoutedEventArgs routedEventArgs) + { + if (Element == null) + return; + + Element.SendAppearing(); + UpdateBounds(); + } + + void OnControlUnlaoded(object sender, RoutedEventArgs routedEventArgs) + { + if (Element == null) + return; + + Element.SendDisappearing(); + } + + void OnDetailPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == Page.TitleProperty.PropertyName || e.PropertyName == NavigationPage.CurrentPageProperty.PropertyName) + UpdateDetailTitle(); + } + + void OnIsPaneOpenChanged(DependencyObject sender, DependencyProperty dp) + { + ((IElementController)Element).SetValueFromRenderer(MasterDetailPage.IsPresentedProperty, Control.IsPaneOpen); + UpdateBounds(); + } + + void OnMasterPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == Page.TitleProperty.PropertyName) + Control.MasterTitle = _master?.Title; + } + + void OnNativeSizeChanged(object sender, SizeChangedEventArgs e) + { + UpdateBounds(); + } + + void UpdateBounds() + { + Windows.Foundation.Size masterSize = Control.MasterSize; + Windows.Foundation.Size detailSize = Control.DetailSize; + + Element.MasterBounds = new Rectangle(0, 0, masterSize.Width, masterSize.Height); + Element.DetailBounds = new Rectangle(0, 0, detailSize.Width, detailSize.Height); + } + + void UpdateDetail() + { + ClearDetail(); + + FrameworkElement element = null; + + _detail = Element.Detail; + if (_detail != null) + { + _detail.PropertyChanged += OnDetailPropertyChanged; + + IVisualElementRenderer renderer = _detail.GetOrCreateRenderer(); + element = renderer.ContainerElement; + } + + Control.Detail = element; + UpdateDetailTitle(); + } + + void UpdateDetailTitle() + { + if (_detail == null) + return; + + Control.DetailTitle = (_detail as NavigationPage)?.CurrentPage?.Title ?? _detail.Title ?? Element?.Title; + } + + void UpdateIsPresented() + { + Control.IsPaneOpen = Element.IsPresented; + } + + void UpdateMaster() + { + ClearMaster(); + + FrameworkElement element = null; + _master = Element.Master; + if (_master != null) + { + _master.PropertyChanged += OnMasterPropertyChanged; + + IVisualElementRenderer renderer = _master.GetOrCreateRenderer(); + element = renderer.ContainerElement; + } + + Control.Master = element; + Control.MasterTitle = _master?.Title; + } + + void UpdateMode() + { + Control.ShouldShowSplitMode = Element.ShouldShowSplitMode; + } + +#if WINDOWS_UWP + public void BindForegroundColor(AppBar appBar) + { + SetAppBarForegroundBinding(appBar); + } + + public void BindForegroundColor(AppBarButton button) + { + SetAppBarForegroundBinding(button); + } + + void SetAppBarForegroundBinding(FrameworkElement element) + { + element.SetBinding(Windows.UI.Xaml.Controls.Control.ForegroundProperty, + new Windows.UI.Xaml.Data.Binding { Path = new PropertyPath("Control.ToolbarForeground"), Source = this, RelativeSource = new RelativeSource { Mode = RelativeSourceMode.TemplatedParent } }); + } +#endif + } +}
\ No newline at end of file |