protected override void OnLayoutCore(bool changed, int left, int top, int right, int bottom)
        {
            var newSize = new Size(right - left, bottom - top).PhysicalToLogicalPixels();

            base.OnLayoutCore(changed, left, top, right, bottom);

            if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
            {
                this.Log().DebugFormat(
                    "[{0}/{1}] OnLayoutCore({2}, {3}, {4}, {5}) (parent: {5},{6})",
                    GetType(),
                    Name,
                    left, top, right, bottom,
                    MeasuredWidth,
                    MeasuredHeight
                    );
            }

            var previousSize = _actualSize;

            _actualSize = newSize;
            RenderSize  = _actualSize;

            if (
                // If the layout has changed, but the final size has not, this is just a translation.
                // So unless there was a layout requested, we can skip arranging the children.
                (changed && _lastLayoutSize != newSize)

                // Even if nothing changed, but a layout was requested, arrang the children.
                || IsLayoutRequested
                )
            {
                _lastLayoutSize = newSize;

                OnBeforeArrange();

                _layouter.Arrange(new Rect(0, 0, newSize.Width, newSize.Height));

                OnLayoutUpdated();
                OnAfterArrange();
            }

            if (previousSize != newSize)
            {
                SizeChanged?.Invoke(this, new SizeChangedEventArgs(previousSize, newSize));
                RenderTransform?.OnViewSizeChanged(previousSize, newSize);
            }
        }