HashSet<string> _batchedProperties = new HashSet<string>();
+ int _layoutCallback = 0;
+
/// <summary>
/// Default constructor.
/// </summary>
public void UpdateNativeGeometry()
{
- var x = ComputeAbsoluteX(Element);
- var y = ComputeAbsoluteY(Element);
- NativeView.Geometry = new Rectangle(x, y, Element.Width, Element.Height).ToPixel();
- ApplyTransformation();
+ var updatedGeometry = new Rectangle(ComputeAbsolutePoint(Element), new Size(Element.Width, Element.Height)).ToPixel();
+
+ if (NativeView.Geometry != updatedGeometry)
+ {
+ NativeView.Geometry = updatedGeometry;
+ ApplyTransformation();
+ }
}
void IVisualElementRenderer.SetElement(VisualElement element)
protected virtual void UpdateLayout()
{
// we're updating the coordinates of native control only if they were modified
- // via Xamarin (Settings.IgnoreBatchCommitted is set to false);
+ // via Xamarin (IsNativeLayouting() returns false);
// otherwise native control is already in the right place
- if (!Settings.IgnoreBatchCommitted && null != NativeView)
+ if (!IsNativeLayouting() && null != NativeView)
{
UpdateNativeGeometry();
}
// we're updating just immediate children
+ // To update the relative postion of children
var logicalChildren = (Element as IElementController).LogicalChildren;
foreach (var child in logicalChildren)
{
Element.FocusChangeRequested -= OnFocusChangeRequested;
- Settings.StartIgnoringBatchCommitted();
Element.Layout(new Rectangle(0, 0, -1, -1));
- Settings.StopIgnoringBatchCommitted();
var logicalChildren = (Element as IElementController).LogicalChildren;
foreach (var child in logicalChildren)
e.OldElement.FocusChangeRequested -= OnFocusChangeRequested;
- Settings.StartIgnoringBatchCommitted();
Element.Layout(new Rectangle(0, 0, -1, -1));
- Settings.StopIgnoringBatchCommitted();
var controller = e.OldElement as IElementController;
if (controller != null && controller.EffectControlProvider == this)
{
if (_flags.HasFlag(VisualElementRendererFlags.NeedsLayout))
{
- if (!Settings.IgnoreBatchCommitted)
+ if (!IsNativeLayouting())
{
- UpdateLayout();
+ UpdateNativeGeometry();
// UpdateLayout already updates transformation, clear NeedsTranformation flag then
_flags &= ~VisualElementRendererFlags.NeedsTransformation;
}
protected void DoLayout(Native.LayoutEventArgs e)
{
- Settings.StartIgnoringBatchCommitted();
-
- Element.Layout(new Rectangle(Element.X, Element.Y, Forms.ConvertToScaledDP(e.Width), Forms.ConvertToScaledDP(e.Height)));
+ EnterNativeLayoutCallback();
if (e.HasChanged)
{
+ var bound = e.Geometry.ToDP();
+ bound.X = Element.X;
+ bound.Y = Element.Y;
+ Element.Layout(bound);
UpdateLayout();
}
- Settings.StopIgnoringBatchCommitted();
+ LeaveNativeLayoutCallback();
}
protected virtual Size MinimumSize()
{
- return new Size();
+ return new ESize(NativeView.MinimumWidth, NativeView.MinimumHeight).ToDP();
}
/// <summary>
return e.Y + (e.RealParent is VisualElement ? Forms.ConvertToScaledDP(Platform.GetRenderer(e.RealParent).NativeView.Geometry.Y) : 0.0);
}
+ static Point ComputeAbsolutePoint(VisualElement e)
+ {
+ return new Point(ComputeAbsoluteX(e), ComputeAbsoluteY(e));
+ }
+
/// <summary>
/// Handles focus events.
/// </summary>
NativeView.EvasMap = map;
}
}
-
EFocusDirection ConvertToNativeFocusDirection(string direction) {
if (direction == XFocusDirection.Back) return EFocusDirection.Previous;
if (direction == XFocusDirection.Forward) return EFocusDirection.Next;
return EFocusDirection.Next;
}
- }
- internal static class Settings
- {
- static int s_ignoreCount = 0;
-
- public static bool IgnoreBatchCommitted
+ void EnterNativeLayoutCallback()
{
- get
- {
- return s_ignoreCount != 0;
- }
+ _layoutCallback++;
}
-
- public static void StartIgnoringBatchCommitted()
+ void LeaveNativeLayoutCallback()
{
- ++s_ignoreCount;
+ _layoutCallback--;
}
-
- public static void StopIgnoringBatchCommitted()
+ bool IsNativeLayouting()
{
- Debug.Assert(s_ignoreCount > 0);
- --s_ignoreCount;
+ return _layoutCallback > 0;
}
}
}