185 строки
4.5 KiB
C#
185 строки
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Collections.Specialized;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
|
|
namespace Xamarin.Forms.Internals
|
|
{
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public class ToolbarTracker
|
|
{
|
|
int _masterDetails;
|
|
Page _target;
|
|
|
|
public IEnumerable<Page> AdditionalTargets { get; set; }
|
|
|
|
public bool HaveMasterDetail
|
|
{
|
|
get { return _masterDetails > 0; }
|
|
}
|
|
|
|
public bool SeparateMasterDetail { get; set; }
|
|
|
|
public Page Target
|
|
{
|
|
get { return _target; }
|
|
set
|
|
{
|
|
if (_target == value)
|
|
return;
|
|
|
|
UntrackTarget(_target);
|
|
_target = value;
|
|
|
|
if (_target != null)
|
|
TrackTarget(_target);
|
|
EmitCollectionChanged();
|
|
}
|
|
}
|
|
|
|
public IEnumerable<ToolbarItem> ToolbarItems
|
|
{
|
|
get
|
|
{
|
|
if (Target == null)
|
|
return Enumerable.Empty<ToolbarItem>();
|
|
IEnumerable<ToolbarItem> items = GetCurrentToolbarItems(Target);
|
|
if (AdditionalTargets != null)
|
|
items = items.Concat(AdditionalTargets.SelectMany(t => t.ToolbarItems));
|
|
|
|
return items.OrderBy(ti => ti.Priority);
|
|
}
|
|
}
|
|
|
|
public event EventHandler CollectionChanged;
|
|
|
|
void EmitCollectionChanged()
|
|
{
|
|
if (CollectionChanged != null)
|
|
CollectionChanged(this, EventArgs.Empty);
|
|
}
|
|
|
|
IEnumerable<ToolbarItem> GetCurrentToolbarItems(Page page)
|
|
{
|
|
var result = new List<ToolbarItem>();
|
|
result.AddRange(page.ToolbarItems);
|
|
|
|
if (page is MasterDetailPage)
|
|
{
|
|
var masterDetail = (MasterDetailPage)page;
|
|
if (SeparateMasterDetail)
|
|
{
|
|
if (masterDetail.IsPresented)
|
|
{
|
|
if (masterDetail.Master != null)
|
|
result.AddRange(GetCurrentToolbarItems(masterDetail.Master));
|
|
}
|
|
else
|
|
{
|
|
if (masterDetail.Detail != null)
|
|
result.AddRange(GetCurrentToolbarItems(masterDetail.Detail));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (masterDetail.Master != null)
|
|
result.AddRange(GetCurrentToolbarItems(masterDetail.Master));
|
|
if (masterDetail.Detail != null)
|
|
result.AddRange(GetCurrentToolbarItems(masterDetail.Detail));
|
|
}
|
|
}
|
|
else if (page is IPageContainer<Page>)
|
|
{
|
|
var container = (IPageContainer<Page>)page;
|
|
if (container.CurrentPage != null)
|
|
result.AddRange(GetCurrentToolbarItems(container.CurrentPage));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void OnChildAdded(object sender, ElementEventArgs eventArgs)
|
|
{
|
|
var page = eventArgs.Element as Page;
|
|
if (page == null)
|
|
return;
|
|
|
|
RegisterChildPage(page);
|
|
}
|
|
|
|
void OnChildRemoved(object sender, ElementEventArgs eventArgs)
|
|
{
|
|
var page = eventArgs.Element as Page;
|
|
if (page == null)
|
|
return;
|
|
|
|
UnregisterChildPage(page);
|
|
}
|
|
|
|
void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
|
|
{
|
|
EmitCollectionChanged();
|
|
}
|
|
|
|
void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
|
|
{
|
|
if (propertyChangedEventArgs.PropertyName == NavigationPage.CurrentPageProperty.PropertyName || propertyChangedEventArgs.PropertyName == MasterDetailPage.IsPresentedProperty.PropertyName ||
|
|
propertyChangedEventArgs.PropertyName == "Detail" || propertyChangedEventArgs.PropertyName == "Master")
|
|
{
|
|
EmitCollectionChanged();
|
|
}
|
|
}
|
|
|
|
void RegisterChildPage(Page page)
|
|
{
|
|
if (page is MasterDetailPage)
|
|
_masterDetails++;
|
|
|
|
((ObservableCollection<ToolbarItem>)page.ToolbarItems).CollectionChanged += OnCollectionChanged;
|
|
page.PropertyChanged += OnPropertyChanged;
|
|
}
|
|
|
|
void TrackTarget(Page page)
|
|
{
|
|
if (page == null)
|
|
return;
|
|
|
|
if (page is MasterDetailPage)
|
|
_masterDetails++;
|
|
|
|
((ObservableCollection<ToolbarItem>)page.ToolbarItems).CollectionChanged += OnCollectionChanged;
|
|
page.Descendants().OfType<Page>().ForEach(RegisterChildPage);
|
|
|
|
page.DescendantAdded += OnChildAdded;
|
|
page.DescendantRemoved += OnChildRemoved;
|
|
page.PropertyChanged += OnPropertyChanged;
|
|
}
|
|
|
|
void UnregisterChildPage(Page page)
|
|
{
|
|
if (page is MasterDetailPage)
|
|
_masterDetails--;
|
|
|
|
((ObservableCollection<ToolbarItem>)page.ToolbarItems).CollectionChanged -= OnCollectionChanged;
|
|
page.PropertyChanged -= OnPropertyChanged;
|
|
}
|
|
|
|
void UntrackTarget(Page page)
|
|
{
|
|
if (page == null)
|
|
return;
|
|
|
|
if (page is MasterDetailPage)
|
|
_masterDetails--;
|
|
|
|
((ObservableCollection<ToolbarItem>)page.ToolbarItems).CollectionChanged -= OnCollectionChanged;
|
|
page.Descendants().OfType<Page>().ForEach(UnregisterChildPage);
|
|
|
|
page.DescendantAdded -= OnChildAdded;
|
|
page.DescendantRemoved -= OnChildRemoved;
|
|
page.PropertyChanged -= OnPropertyChanged;
|
|
}
|
|
}
|
|
} |