summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs')
-rw-r--r--Xamarin.Forms.Platform.UAP/MasterDetailPageRenderer.cs312
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