2016-03-22 23:02:25 +03:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Specialized;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using Windows.UI.Xaml;
|
|
|
|
|
using Windows.UI.Xaml.Automation;
|
|
|
|
|
using Windows.UI.Xaml.Controls;
|
|
|
|
|
using Windows.UI.Xaml.Media;
|
2016-06-17 13:10:18 +03:00
|
|
|
|
using Xamarin.Forms.Internals;
|
2016-07-19 02:33:41 +03:00
|
|
|
|
using WGrid = Windows.UI.Xaml.Controls.Grid;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
|
|
|
|
namespace Xamarin.Forms.Platform.WinRT
|
|
|
|
|
{
|
2016-04-18 19:46:51 +03:00
|
|
|
|
internal class TabbedPagePresenter : Windows.UI.Xaml.Controls.ContentPresenter
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2016-04-18 19:46:51 +03:00
|
|
|
|
public TabbedPagePresenter()
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2016-07-19 02:33:41 +03:00
|
|
|
|
SizeChanged += (s, e) =>
|
|
|
|
|
{
|
2016-04-18 19:46:51 +03:00
|
|
|
|
if (ActualWidth > 0 && ActualHeight > 0)
|
|
|
|
|
{
|
|
|
|
|
var tab = ((Page)DataContext);
|
2017-04-11 21:02:06 +03:00
|
|
|
|
((Page)tab.RealParent).ContainerArea = new Rectangle(0, 0, ActualWidth, ActualHeight);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class TabbedPageRenderer
|
|
|
|
|
: IVisualElementRenderer, ITitleProvider
|
|
|
|
|
{
|
2016-07-19 02:33:41 +03:00
|
|
|
|
const string TabBarHeaderTextBlockName = "TabbedPageHeaderTextBlock";
|
|
|
|
|
const string TabBarHeaderGridName = "TabbedPageHeaderGrid";
|
|
|
|
|
|
|
|
|
|
Color _barBackgroundColor;
|
|
|
|
|
Color _barTextColor;
|
|
|
|
|
bool _disposed;
|
|
|
|
|
VisualElementTracker<Page, Pivot> _tracker;
|
|
|
|
|
bool _showTitle;
|
|
|
|
|
|
|
|
|
|
ITitleProvider TitleProvider => this;
|
|
|
|
|
|
2016-03-22 23:02:25 +03:00
|
|
|
|
public event EventHandler<VisualElementChangedEventArgs> ElementChanged;
|
|
|
|
|
|
|
|
|
|
public FrameworkElement ContainerElement
|
|
|
|
|
{
|
|
|
|
|
get { return Control; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VisualElement IVisualElementRenderer.Element
|
|
|
|
|
{
|
|
|
|
|
get { return Element; }
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
public FormsPivot Control
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
get;
|
|
|
|
|
private set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TabbedPage Element
|
|
|
|
|
{
|
|
|
|
|
get;
|
|
|
|
|
private set;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
public void SetElement(VisualElement element)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
if (element != null && !(element is TabbedPage))
|
2016-04-18 19:46:51 +03:00
|
|
|
|
throw new ArgumentException("Element must be a TabbedPage", "element");
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
|
|
|
|
TabbedPage oldElement = Element;
|
2016-04-18 19:46:51 +03:00
|
|
|
|
Element = (TabbedPage)element;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
if (oldElement != null)
|
|
|
|
|
{
|
2016-03-22 23:02:25 +03:00
|
|
|
|
oldElement.PropertyChanged -= OnElementPropertyChanged;
|
2016-04-18 19:46:51 +03:00
|
|
|
|
((INotifyCollectionChanged)oldElement.Children).CollectionChanged -= OnPagesChanged;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
if (element != null)
|
|
|
|
|
{
|
|
|
|
|
if (Control == null)
|
|
|
|
|
{
|
2016-07-19 02:33:41 +03:00
|
|
|
|
Control = new FormsPivot
|
|
|
|
|
{
|
|
|
|
|
Style = (Windows.UI.Xaml.Style)Windows.UI.Xaml.Application.Current.Resources["TabbedPageStyle"],
|
|
|
|
|
ItemTemplate = (Windows.UI.Xaml.DataTemplate)Windows.UI.Xaml.Application.Current.Resources["TabbedPage"]
|
2016-03-22 23:02:25 +03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Control.SelectionChanged += OnSelectionChanged;
|
|
|
|
|
|
2016-07-19 02:33:41 +03:00
|
|
|
|
Tracker = new BackgroundTracker<Pivot>(Windows.UI.Xaml.Controls.Control.BackgroundProperty)
|
|
|
|
|
{
|
2016-04-18 19:46:51 +03:00
|
|
|
|
Element = (Page)element,
|
2016-03-22 23:02:25 +03:00
|
|
|
|
Control = Control,
|
|
|
|
|
Container = Control
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Control.Loaded += OnLoaded;
|
|
|
|
|
Control.Unloaded += OnUnloaded;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Control.DataContext = Element;
|
2016-04-18 19:46:51 +03:00
|
|
|
|
OnPagesChanged(Element.Children, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
2016-07-19 02:33:41 +03:00
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
UpdateCurrentPage();
|
|
|
|
|
|
|
|
|
|
((INotifyCollectionChanged)Element.Children).CollectionChanged += OnPagesChanged;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
element.PropertyChanged += OnElementPropertyChanged;
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
if (!string.IsNullOrEmpty(element.AutomationId))
|
2017-05-10 20:20:57 +03:00
|
|
|
|
Control.SetValue(Windows.UI.Xaml.Automation.AutomationProperties.AutomationIdProperty, element.AutomationId);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
OnElementChanged(new VisualElementChangedEventArgs(oldElement, element));
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
public SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2016-04-18 19:46:51 +03:00
|
|
|
|
var constraint = new Windows.Foundation.Size(widthConstraint, heightConstraint);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
|
|
|
|
var oldWidth = Control.Width;
|
|
|
|
|
var oldHeight = Control.Height;
|
|
|
|
|
|
|
|
|
|
Control.Height = double.NaN;
|
|
|
|
|
Control.Width = double.NaN;
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
Control.Measure(constraint);
|
|
|
|
|
var result = new Size(Math.Ceiling(Control.DesiredSize.Width), Math.Ceiling(Control.DesiredSize.Height));
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
|
|
|
|
Control.Width = oldWidth;
|
|
|
|
|
Control.Height = oldHeight;
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
return new SizeRequest(result);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-01-31 22:49:15 +03:00
|
|
|
|
UIElement IVisualElementRenderer.GetNativeElement()
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
public void Dispose()
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2016-04-18 19:46:51 +03:00
|
|
|
|
Dispose(true);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
protected virtual void Dispose(bool disposing)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
if (!disposing || _disposed)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
_disposed = true;
|
2016-10-11 19:56:20 +03:00
|
|
|
|
|
2017-04-11 21:02:06 +03:00
|
|
|
|
Element?.SendDisappearing();
|
2016-04-18 19:46:51 +03:00
|
|
|
|
SetElement(null);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
Tracker = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected VisualElementTracker<Page, Pivot> Tracker
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return _tracker;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_tracker == value)
|
|
|
|
|
return;
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
if (_tracker != null)
|
|
|
|
|
{
|
|
|
|
|
_tracker.Dispose();
|
2016-03-22 23:02:25 +03:00
|
|
|
|
/*this.tracker.Updated -= OnTrackerUpdated;*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_tracker = value;
|
|
|
|
|
|
|
|
|
|
/*if (this.tracker != null)
|
|
|
|
|
this.tracker.Updated += OnTrackerUpdated;*/
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-04-18 19:46:51 +03:00
|
|
|
|
|
|
|
|
|
bool ITitleProvider.ShowTitle
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return _showTitle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_showTitle == value)
|
|
|
|
|
return;
|
|
|
|
|
_showTitle = value;
|
2016-04-18 19:46:51 +03:00
|
|
|
|
|
2016-08-30 20:46:14 +03:00
|
|
|
|
Control.TitleVisibility = _showTitle ? Visibility.Visible : Visibility.Collapsed;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
string ITitleProvider.Title
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return (string)Control?.Title;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (Control != null)
|
|
|
|
|
Control.Title = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Brush ITitleProvider.BarBackgroundBrush
|
|
|
|
|
{
|
|
|
|
|
set
|
|
|
|
|
{
|
2016-07-19 02:33:41 +03:00
|
|
|
|
Control.ToolbarBackground = value;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Brush ITitleProvider.BarForegroundBrush
|
|
|
|
|
{
|
|
|
|
|
set
|
|
|
|
|
{
|
2016-07-19 02:33:41 +03:00
|
|
|
|
Control.ToolbarForeground = value;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
protected virtual void OnElementChanged(VisualElementChangedEventArgs e)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
var changed = ElementChanged;
|
|
|
|
|
if (changed != null)
|
2016-04-18 19:46:51 +03:00
|
|
|
|
changed(this, e);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
void OnPagesChanged(object sender, NotifyCollectionChangedEventArgs e)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2016-04-18 19:46:51 +03:00
|
|
|
|
e.Apply(Element.Children, Control.Items);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
|
|
|
|
// Potential performance issue, UpdateLayout () is called for every page change
|
2016-04-18 19:46:51 +03:00
|
|
|
|
Control.UpdateLayout();
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
if (Element == null)
|
|
|
|
|
return;
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
Page page = (e.AddedItems.Count > 0) ? (Page)e.AddedItems[0] : null;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
Element.CurrentPage = page;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2016-04-18 19:46:51 +03:00
|
|
|
|
if (e.PropertyName == nameof(TabbedPage.CurrentPage))
|
2016-07-19 02:33:41 +03:00
|
|
|
|
{
|
2016-04-18 19:46:51 +03:00
|
|
|
|
UpdateCurrentPage();
|
2016-07-19 02:33:41 +03:00
|
|
|
|
UpdateBarTextColor();
|
|
|
|
|
UpdateBarBackgroundColor();
|
|
|
|
|
}
|
2016-04-18 19:46:51 +03:00
|
|
|
|
else if (e.PropertyName == TabbedPage.BarTextColorProperty.PropertyName)
|
|
|
|
|
UpdateBarTextColor();
|
|
|
|
|
else if (e.PropertyName == TabbedPage.BarBackgroundColorProperty.PropertyName)
|
|
|
|
|
UpdateBarBackgroundColor();
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
void UpdateCurrentPage()
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
Page page = Element.CurrentPage;
|
2016-04-18 19:46:51 +03:00
|
|
|
|
UpdateTitle(page);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
|
|
|
|
if (page == null)
|
|
|
|
|
return;
|
|
|
|
|
Control.SelectedItem = page;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
void OnLoaded(object sender, RoutedEventArgs args)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2017-04-11 21:02:06 +03:00
|
|
|
|
Element?.SendAppearing();
|
2016-07-19 02:33:41 +03:00
|
|
|
|
UpdateBarTextColor();
|
|
|
|
|
UpdateBarBackgroundColor();
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
void OnUnloaded(object sender, RoutedEventArgs args)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2017-04-11 21:02:06 +03:00
|
|
|
|
Element?.SendDisappearing();
|
2016-04-18 19:46:51 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnTrackerUpdated(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Brush GetBarBackgroundBrush()
|
|
|
|
|
{
|
|
|
|
|
object defaultColor = Windows.UI.Xaml.Application.Current.Resources["AppBarBackgroundThemeBrush"];
|
|
|
|
|
if (Element.BarBackgroundColor.IsDefault && defaultColor != null)
|
|
|
|
|
return (Brush)defaultColor;
|
|
|
|
|
return Element.BarBackgroundColor.ToBrush();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Brush GetBarForegroundBrush()
|
|
|
|
|
{
|
|
|
|
|
object defaultColor = Windows.UI.Xaml.Application.Current.Resources["AppBarItemForegroundThemeBrush"];
|
2016-07-19 02:33:41 +03:00
|
|
|
|
if (Element.BarTextColor.IsDefault && defaultColor != null)
|
2016-04-18 19:46:51 +03:00
|
|
|
|
return (Brush)defaultColor;
|
|
|
|
|
return Element.BarTextColor.ToBrush();
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
void UpdateBarBackgroundColor()
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2016-07-19 02:33:41 +03:00
|
|
|
|
if (Element == null) return;
|
|
|
|
|
var barBackgroundColor = Element.BarBackgroundColor;
|
|
|
|
|
|
|
|
|
|
if (barBackgroundColor == _barBackgroundColor) return;
|
|
|
|
|
_barBackgroundColor = barBackgroundColor;
|
|
|
|
|
|
|
|
|
|
var controlToolbarBackground = Control.ToolbarBackground;
|
|
|
|
|
if (controlToolbarBackground == null && barBackgroundColor.IsDefault) return;
|
|
|
|
|
|
|
|
|
|
var brush = GetBarBackgroundBrush();
|
|
|
|
|
if (brush == controlToolbarBackground) return;
|
|
|
|
|
|
|
|
|
|
TitleProvider.BarBackgroundBrush = brush;
|
|
|
|
|
|
|
|
|
|
foreach (WGrid tabBarGrid in Control.GetDescendantsByName<WGrid>(TabBarHeaderGridName))
|
|
|
|
|
{
|
|
|
|
|
tabBarGrid.Background = brush;
|
|
|
|
|
}
|
2016-04-18 19:46:51 +03:00
|
|
|
|
}
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
void UpdateBarTextColor()
|
|
|
|
|
{
|
2016-07-19 02:33:41 +03:00
|
|
|
|
if (Element == null) return;
|
|
|
|
|
var barTextColor = Element.BarTextColor;
|
|
|
|
|
|
|
|
|
|
if (barTextColor == _barTextColor) return;
|
|
|
|
|
_barTextColor = barTextColor;
|
|
|
|
|
|
|
|
|
|
var controlToolbarForeground = Control.ToolbarForeground;
|
|
|
|
|
if (controlToolbarForeground == null && barTextColor.IsDefault) return;
|
|
|
|
|
|
|
|
|
|
var brush = GetBarForegroundBrush();
|
|
|
|
|
if (brush == controlToolbarForeground) return;
|
|
|
|
|
|
|
|
|
|
TitleProvider.BarForegroundBrush = brush;
|
|
|
|
|
|
|
|
|
|
foreach (TextBlock tabBarTextBlock in Control.GetDescendantsByName<TextBlock>(TabBarHeaderTextBlockName))
|
|
|
|
|
{
|
|
|
|
|
tabBarTextBlock.Foreground = brush;
|
|
|
|
|
}
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-18 19:46:51 +03:00
|
|
|
|
void UpdateTitle(Page child)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2016-04-18 19:46:51 +03:00
|
|
|
|
Control.ClearValue(Pivot.TitleProperty);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
|
|
|
|
if (child == null)
|
|
|
|
|
return;
|
2016-04-18 19:46:51 +03:00
|
|
|
|
var renderer = Platform.GetRenderer(child);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
var navigationRenderer = renderer as NavigationPageRenderer;
|
2016-04-18 19:46:51 +03:00
|
|
|
|
if (navigationRenderer != null)
|
|
|
|
|
{
|
2016-03-22 23:02:25 +03:00
|
|
|
|
Control.Title = navigationRenderer.Title;
|
2016-04-18 19:46:51 +03:00
|
|
|
|
}
|
2016-07-19 02:33:41 +03:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TitleProvider.ShowTitle = false;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|