maui-linux/Xamarin.Forms.Platform.WinR.../TabbedPageRenderer.cs

373 строки
8.5 KiB
C#
Исходник Обычный вид История

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;
using Xamarin.Forms.Internals;
using WGrid = Windows.UI.Xaml.Controls.Grid;
2016-03-22 23:02:25 +03:00
namespace Xamarin.Forms.Platform.WinRT
{
internal class TabbedPagePresenter : Windows.UI.Xaml.Controls.ContentPresenter
2016-03-22 23:02:25 +03:00
{
public TabbedPagePresenter()
2016-03-22 23:02:25 +03:00
{
SizeChanged += (s, e) =>
{
if (ActualWidth > 0 && ActualHeight > 0)
{
var tab = ((Page)DataContext);
((Page)tab.RealParent).ContainerArea = new Rectangle(0, 0, ActualWidth, ActualHeight);
2016-03-22 23:02:25 +03:00
}
};
}
}
public class TabbedPageRenderer
: IVisualElementRenderer, ITitleProvider
{
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; }
}
public FormsPivot Control
2016-03-22 23:02:25 +03:00
{
get;
private set;
}
public TabbedPage Element
{
get;
private set;
}
public void SetElement(VisualElement element)
2016-03-22 23:02:25 +03:00
{
if (element != null && !(element is TabbedPage))
throw new ArgumentException("Element must be a TabbedPage", "element");
2016-03-22 23:02:25 +03:00
TabbedPage oldElement = Element;
Element = (TabbedPage)element;
2016-03-22 23:02:25 +03:00
if (oldElement != null)
{
2016-03-22 23:02:25 +03:00
oldElement.PropertyChanged -= OnElementPropertyChanged;
((INotifyCollectionChanged)oldElement.Children).CollectionChanged -= OnPagesChanged;
2016-03-22 23:02:25 +03:00
}
if (element != null)
{
if (Control == null)
{
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;
Tracker = new BackgroundTracker<Pivot>(Windows.UI.Xaml.Controls.Control.BackgroundProperty)
{
Element = (Page)element,
2016-03-22 23:02:25 +03:00
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;
2016-03-22 23:02:25 +03:00
element.PropertyChanged += OnElementPropertyChanged;
if (!string.IsNullOrEmpty(element.AutomationId))
Control.SetValue(Windows.UI.Xaml.Automation.AutomationProperties.AutomationIdProperty, element.AutomationId);
2016-03-22 23:02:25 +03:00
}
OnElementChanged(new VisualElementChangedEventArgs(oldElement, element));
2016-03-22 23:02:25 +03:00
}
public SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint)
2016-03-22 23:02:25 +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;
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;
return new SizeRequest(result);
2016-03-22 23:02:25 +03:00
}
UIElement IVisualElementRenderer.GetNativeElement()
{
return null;
}
public void Dispose()
2016-03-22 23:02:25 +03:00
{
Dispose(true);
2016-03-22 23:02:25 +03:00
}
protected virtual void Dispose(bool disposing)
2016-03-22 23:02:25 +03:00
{
if (!disposing || _disposed)
return;
_disposed = true;
Element?.SendDisappearing();
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;
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;*/
}
}
bool ITitleProvider.ShowTitle
2016-03-22 23:02:25 +03:00
{
get
{
return _showTitle;
}
set
{
if (_showTitle == value)
return;
_showTitle = value;
Platform Specifics (#301) * Playing around with how the platform specifics interfaces etc. might work * Sample implementation of iOS navigation translucency * Very slightly reduced code * Better vendor stuff * Drop single-implemenation interfaces * Generics on NavigationPage * On-demand vendor stuff * Remove functionally duplicate classes and make ControlGallery work again * Namespace all the things. XAML test. * Can use Effect to attach platform specific * Attach Effect on PropertyChanging for XAML support! * Rename IConfigPlatform interfaces for readability * Some renaming to match the documents * Split class files * Clear out test-only code * Re-namespace * Added On method to rendered Elements * Allow for removal of platform suffix, convenience methods on specific platforms * Creating a gallery page for specifics * Add rudimentary Platform Specifics gallery; make CollapseStyle work on UWP; Add CollapsedPaneWidth specific property * Toolbar now working with both collapse styles * MDP now displaying Content title; toolbar routing around title * Add a gallery for the iOS NavigationPage stuff * Add Navigation Page as detail page to verify it works with new Toolbar options * Make titlebar/toolbar background colors consistent * ToolbarPlacement now working on NavigationPage * Toolbar Placement working for tabbed and nav pages * Fix bug where phone doesn't get default toolbar placement on start * [Core] Add PS WindowSoftInputModeAdjust [Core] Make Application extendable * Toolbar placement now working on Nav, Tabbed, and Master pages on desktop/phone Remove unnecessary style indirection Fix build errors * [A] Add PlatformConfigurationExtensions * SetSoftInputMode test page * [A] SetSoftInputMode Known issue: Status bar color does not work in AdjustResize mode * [Core] Add PS Blur * [iOS] Configure renderer for blur * Add test page * Move to blur VisualElement for broader support * Move test pages to gallery * Update docs * Use lazy initializer for PlatformConfigurationRegistry
2016-08-30 20:46:14 +03:00
Control.TitleVisibility = _showTitle ? Visibility.Visible : Visibility.Collapsed;
2016-03-22 23:02:25 +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
{
Control.ToolbarBackground = value;
2016-03-22 23:02:25 +03:00
}
}
Brush ITitleProvider.BarForegroundBrush
{
set
{
Control.ToolbarForeground = value;
2016-03-22 23:02:25 +03:00
}
}
protected virtual void OnElementChanged(VisualElementChangedEventArgs e)
2016-03-22 23:02:25 +03:00
{
var changed = ElementChanged;
if (changed != null)
changed(this, e);
2016-03-22 23:02:25 +03:00
}
void OnPagesChanged(object sender, NotifyCollectionChangedEventArgs e)
2016-03-22 23:02:25 +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
Control.UpdateLayout();
2016-03-22 23:02:25 +03:00
}
void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
2016-03-22 23:02:25 +03:00
{
if (Element == null)
return;
Page page = (e.AddedItems.Count > 0) ? (Page)e.AddedItems[0] : null;
2016-03-22 23:02:25 +03:00
Element.CurrentPage = page;
}
void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
2016-03-22 23:02:25 +03:00
{
if (e.PropertyName == nameof(TabbedPage.CurrentPage))
{
UpdateCurrentPage();
UpdateBarTextColor();
UpdateBarBackgroundColor();
}
else if (e.PropertyName == TabbedPage.BarTextColorProperty.PropertyName)
UpdateBarTextColor();
else if (e.PropertyName == TabbedPage.BarBackgroundColorProperty.PropertyName)
UpdateBarBackgroundColor();
2016-03-22 23:02:25 +03:00
}
void UpdateCurrentPage()
2016-03-22 23:02:25 +03:00
{
Page page = Element.CurrentPage;
UpdateTitle(page);
2016-03-22 23:02:25 +03:00
if (page == null)
return;
Control.SelectedItem = page;
}
void OnLoaded(object sender, RoutedEventArgs args)
2016-03-22 23:02:25 +03:00
{
Element?.SendAppearing();
UpdateBarTextColor();
UpdateBarBackgroundColor();
2016-03-22 23:02:25 +03:00
}
void OnUnloaded(object sender, RoutedEventArgs args)
2016-03-22 23:02:25 +03:00
{
Element?.SendDisappearing();
}
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"];
if (Element.BarTextColor.IsDefault && defaultColor != null)
return (Brush)defaultColor;
return Element.BarTextColor.ToBrush();
2016-03-22 23:02:25 +03:00
}
void UpdateBarBackgroundColor()
2016-03-22 23:02:25 +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-03-22 23:02:25 +03:00
void UpdateBarTextColor()
{
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
}
void UpdateTitle(Page child)
2016-03-22 23:02:25 +03:00
{
Control.ClearValue(Pivot.TitleProperty);
2016-03-22 23:02:25 +03:00
if (child == null)
return;
var renderer = Platform.GetRenderer(child);
2016-03-22 23:02:25 +03:00
var navigationRenderer = renderer as NavigationPageRenderer;
if (navigationRenderer != null)
{
2016-03-22 23:02:25 +03:00
Control.Title = navigationRenderer.Title;
}
else
{
TitleProvider.ShowTitle = false;
2016-03-22 23:02:25 +03:00
}
}
}
}