зеркало из https://github.com/DeGsoft/maui-linux.git
175 строки
4.6 KiB
C#
175 строки
4.6 KiB
C#
using System;
|
|
using System.Collections.ObjectModel;
|
|
using global::Windows.UI.Xaml.Controls;
|
|
|
|
namespace System.Maui.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;
|
|
}
|
|
|
|
IElementController ElementController => _renderer.Element as IElementController;
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (_disposed)
|
|
return;
|
|
|
|
_disposed = true;
|
|
|
|
if (ElementController != null)
|
|
{
|
|
for (var i = 0; i < ElementController.LogicalChildren.Count; i++)
|
|
{
|
|
var child = ElementController.LogicalChildren[i] as VisualElement;
|
|
child?.Cleanup();
|
|
}
|
|
}
|
|
|
|
VisualElement element = _renderer.Element;
|
|
if (element != null)
|
|
{
|
|
element.ChildAdded -= OnChildAdded;
|
|
element.ChildRemoved -= OnChildRemoved;
|
|
element.ChildrenReordered -= OnChildrenReordered;
|
|
}
|
|
}
|
|
|
|
public void Load()
|
|
{
|
|
if (_isLoaded)
|
|
return;
|
|
|
|
_isLoaded = true;
|
|
_renderer.Element.ChildAdded += OnChildAdded;
|
|
_renderer.Element.ChildRemoved += OnChildRemoved;
|
|
_renderer.Element.ChildrenReordered += OnChildrenReordered;
|
|
|
|
ReadOnlyCollection<Element> children = ElementController.LogicalChildren;
|
|
for (var i = 0; i < children.Count; i++)
|
|
{
|
|
var view = children[i] as VisualElement;
|
|
if (view == null) continue;
|
|
|
|
SetupVisualElement(view);
|
|
}
|
|
}
|
|
|
|
void EnsureZIndex()
|
|
{
|
|
if (ElementController.LogicalChildren.Count == 0)
|
|
return;
|
|
|
|
for (var z = 0; z < ElementController.LogicalChildren.Count; z++)
|
|
{
|
|
var child = ElementController.LogicalChildren[z] as VisualElement;
|
|
if (child == null)
|
|
continue;
|
|
|
|
IVisualElementRenderer childRenderer = Platform.GetRenderer(child);
|
|
|
|
if (childRenderer == null)
|
|
continue;
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
void SetupVisualElement(VisualElement view)
|
|
{
|
|
IVisualElementRenderer childRenderer = Platform.CreateRenderer(view);
|
|
Platform.SetRenderer(view, childRenderer);
|
|
|
|
if (_row > 0)
|
|
global::Windows.UI.Xaml.Controls.Grid.SetRow(childRenderer.ContainerElement, _row);
|
|
if (_rowSpan > 0)
|
|
global::Windows.UI.Xaml.Controls.Grid.SetRowSpan(childRenderer.ContainerElement, _rowSpan);
|
|
if (_column > 0)
|
|
global::Windows.UI.Xaml.Controls.Grid.SetColumn(childRenderer.ContainerElement, _column);
|
|
if (_columnSpan > 0)
|
|
global::Windows.UI.Xaml.Controls.Grid.SetColumnSpan(childRenderer.ContainerElement, _columnSpan);
|
|
|
|
_panel.Children.Add(childRenderer.ContainerElement);
|
|
}
|
|
|
|
void OnChildAdded(object sender, ElementEventArgs e)
|
|
{
|
|
var view = e.Element as VisualElement;
|
|
|
|
if (view == null)
|
|
return;
|
|
|
|
SetupVisualElement(view);
|
|
if (ElementController.LogicalChildren[ElementController.LogicalChildren.Count - 1] != view)
|
|
EnsureZIndex();
|
|
|
|
}
|
|
|
|
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(global::Windows.UI.Xaml.Controls.Grid.RowProperty);
|
|
if (_rowSpan > 0)
|
|
childRenderer.ContainerElement.ClearValue(global::Windows.UI.Xaml.Controls.Grid.RowSpanProperty);
|
|
if (_column > 0)
|
|
childRenderer.ContainerElement.ClearValue(global::Windows.UI.Xaml.Controls.Grid.ColumnProperty);
|
|
if (_columnSpan > 0)
|
|
childRenderer.ContainerElement.ClearValue(global::Windows.UI.Xaml.Controls.Grid.ColumnSpanProperty);
|
|
|
|
_panel.Children.Remove(childRenderer.ContainerElement);
|
|
|
|
view.Cleanup();
|
|
}
|
|
}
|
|
|
|
void OnChildrenReordered(object sender, EventArgs e)
|
|
{
|
|
EnsureZIndex();
|
|
}
|
|
}
|
|
} |