2016-03-22 23:02:25 +03:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
using Windows.UI.Xaml.Controls;
|
|
|
|
|
|
|
|
|
|
namespace Xamarin.Forms.Platform.UWP
|
|
|
|
|
{
|
|
|
|
|
public class VisualElementPackager : IDisposable
|
|
|
|
|
{
|
|
|
|
|
readonly int _column;
|
|
|
|
|
readonly int _columnSpan;
|
|
|
|
|
|
|
|
|
|
readonly Panel _panel;
|
|
|
|
|
readonly IVisualElementRenderer _renderer;
|
|
|
|
|
readonly int _row;
|
|
|
|
|
readonly int _rowSpan;
|
|
|
|
|
bool _disposed;
|
|
|
|
|
bool _isLoaded;
|
|
|
|
|
|
|
|
|
|
public VisualElementPackager(IVisualElementRenderer renderer)
|
|
|
|
|
{
|
|
|
|
|
if (renderer == null)
|
|
|
|
|
throw new ArgumentNullException("renderer");
|
|
|
|
|
|
|
|
|
|
_renderer = renderer;
|
|
|
|
|
|
|
|
|
|
_panel = renderer.ContainerElement as Panel;
|
|
|
|
|
if (_panel == null)
|
|
|
|
|
throw new ArgumentException("Renderer's container element must be a Panel");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public VisualElementPackager(IVisualElementRenderer renderer, int row = 0, int rowSpan = 0, int column = 0, int columnSpan = 0) : this(renderer)
|
|
|
|
|
{
|
|
|
|
|
_row = row;
|
|
|
|
|
_rowSpan = rowSpan;
|
|
|
|
|
_column = column;
|
|
|
|
|
_columnSpan = columnSpan;
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-16 18:45:09 +03:00
|
|
|
|
IElementController ElementController => _renderer.Element as IElementController;
|
|
|
|
|
|
2016-03-22 23:02:25 +03:00
|
|
|
|
public void Dispose()
|
2016-09-22 01:04:36 +03:00
|
|
|
|
{
|
|
|
|
|
Dispose(true);
|
|
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual void Dispose(bool disposing)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
if (_disposed)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
_disposed = true;
|
|
|
|
|
|
2018-04-30 19:46:03 +03:00
|
|
|
|
if (ElementController != null)
|
|
|
|
|
{
|
|
|
|
|
for (var i = 0; i < ElementController.LogicalChildren.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var child = ElementController.LogicalChildren[i] as VisualElement;
|
|
|
|
|
child?.Cleanup();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-22 23:02:25 +03:00
|
|
|
|
VisualElement element = _renderer.Element;
|
|
|
|
|
if (element != null)
|
|
|
|
|
{
|
|
|
|
|
element.ChildAdded -= OnChildAdded;
|
|
|
|
|
element.ChildRemoved -= OnChildRemoved;
|
2017-06-15 01:14:03 +03:00
|
|
|
|
element.ChildrenReordered -= OnChildrenReordered;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Load()
|
|
|
|
|
{
|
|
|
|
|
if (_isLoaded)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
_isLoaded = true;
|
|
|
|
|
_renderer.Element.ChildAdded += OnChildAdded;
|
|
|
|
|
_renderer.Element.ChildRemoved += OnChildRemoved;
|
2017-06-15 01:14:03 +03:00
|
|
|
|
_renderer.Element.ChildrenReordered += OnChildrenReordered;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
2016-06-16 18:45:09 +03:00
|
|
|
|
ReadOnlyCollection<Element> children = ElementController.LogicalChildren;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
for (var i = 0; i < children.Count; i++)
|
|
|
|
|
{
|
2018-06-07 20:37:12 +03:00
|
|
|
|
var view = children[i] as VisualElement;
|
|
|
|
|
if (view == null) continue;
|
|
|
|
|
|
|
|
|
|
SetupVisualElement(view);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EnsureZIndex()
|
|
|
|
|
{
|
2016-06-16 18:45:09 +03:00
|
|
|
|
if (ElementController.LogicalChildren.Count == 0)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
return;
|
|
|
|
|
|
2016-06-16 18:45:09 +03:00
|
|
|
|
for (var z = 0; z < ElementController.LogicalChildren.Count; z++)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
2016-06-16 18:45:09 +03:00
|
|
|
|
var child = ElementController.LogicalChildren[z] as VisualElement;
|
2016-03-22 23:02:25 +03:00
|
|
|
|
if (child == null)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
IVisualElementRenderer childRenderer = Platform.GetRenderer(child);
|
|
|
|
|
|
|
|
|
|
if (childRenderer == null)
|
|
|
|
|
continue;
|
|
|
|
|
|
2018-06-07 20:37:12 +03:00
|
|
|
|
// default ZIndex is -1 so subtract another one to get everyone below default
|
|
|
|
|
var zIndex = (z - ElementController.LogicalChildren.Count) - 1;
|
|
|
|
|
if (Canvas.GetZIndex(childRenderer.ContainerElement) != (zIndex))
|
|
|
|
|
Canvas.SetZIndex(childRenderer.ContainerElement, zIndex);
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-07 20:37:12 +03:00
|
|
|
|
void SetupVisualElement(VisualElement view)
|
2016-03-22 23:02:25 +03:00
|
|
|
|
{
|
|
|
|
|
IVisualElementRenderer childRenderer = Platform.CreateRenderer(view);
|
|
|
|
|
Platform.SetRenderer(view, childRenderer);
|
|
|
|
|
|
|
|
|
|
if (_row > 0)
|
|
|
|
|
Windows.UI.Xaml.Controls.Grid.SetRow(childRenderer.ContainerElement, _row);
|
|
|
|
|
if (_rowSpan > 0)
|
|
|
|
|
Windows.UI.Xaml.Controls.Grid.SetRowSpan(childRenderer.ContainerElement, _rowSpan);
|
|
|
|
|
if (_column > 0)
|
|
|
|
|
Windows.UI.Xaml.Controls.Grid.SetColumn(childRenderer.ContainerElement, _column);
|
|
|
|
|
if (_columnSpan > 0)
|
|
|
|
|
Windows.UI.Xaml.Controls.Grid.SetColumnSpan(childRenderer.ContainerElement, _columnSpan);
|
|
|
|
|
|
|
|
|
|
_panel.Children.Add(childRenderer.ContainerElement);
|
2018-06-07 20:37:12 +03:00
|
|
|
|
}
|
2016-03-22 23:02:25 +03:00
|
|
|
|
|
2018-06-07 20:37:12 +03:00
|
|
|
|
void OnChildAdded(object sender, ElementEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var view = e.Element as VisualElement;
|
|
|
|
|
|
|
|
|
|
if (view == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
SetupVisualElement(view);
|
2018-05-23 17:47:38 +03:00
|
|
|
|
if (ElementController.LogicalChildren[ElementController.LogicalChildren.Count - 1] != view)
|
2017-12-19 15:39:53 +03:00
|
|
|
|
EnsureZIndex();
|
2018-06-07 20:37:12 +03:00
|
|
|
|
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnChildRemoved(object sender, ElementEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var view = e.Element as VisualElement;
|
|
|
|
|
|
|
|
|
|
if (view == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
IVisualElementRenderer childRenderer = Platform.GetRenderer(view);
|
|
|
|
|
if (childRenderer != null)
|
|
|
|
|
{
|
|
|
|
|
if (_row > 0)
|
|
|
|
|
childRenderer.ContainerElement.ClearValue(Windows.UI.Xaml.Controls.Grid.RowProperty);
|
|
|
|
|
if (_rowSpan > 0)
|
|
|
|
|
childRenderer.ContainerElement.ClearValue(Windows.UI.Xaml.Controls.Grid.RowSpanProperty);
|
|
|
|
|
if (_column > 0)
|
|
|
|
|
childRenderer.ContainerElement.ClearValue(Windows.UI.Xaml.Controls.Grid.ColumnProperty);
|
|
|
|
|
if (_columnSpan > 0)
|
|
|
|
|
childRenderer.ContainerElement.ClearValue(Windows.UI.Xaml.Controls.Grid.ColumnSpanProperty);
|
|
|
|
|
|
|
|
|
|
_panel.Children.Remove(childRenderer.ContainerElement);
|
|
|
|
|
|
|
|
|
|
view.Cleanup();
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-15 01:14:03 +03:00
|
|
|
|
|
|
|
|
|
void OnChildrenReordered(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
EnsureZIndex();
|
|
|
|
|
}
|
2016-03-22 23:02:25 +03:00
|
|
|
|
}
|
|
|
|
|
}
|