Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public class ContainerControl : ScrollableControl, IContainerControl
/// </summary>
private bool _isScaledByDpiChangedEvent;

/// <summary>
/// Indicates scaling, due to DPI changed event, of the container control is in progress.
/// </summary>
internal bool _dpiScalingInProgress;

private BitVector32 _state;

/// <summary>
Expand Down Expand Up @@ -1441,6 +1446,8 @@ internal void ScaleContainerForDpi(int deviceDpiNew, int deviceDpiOld, Rectangle
SuspendAllLayout(this);
try
{
_dpiScalingInProgress = true;

if (LocalAppContextSwitches.ScaleTopLevelFormMinMaxSizeForDpi)
{
// The suggested rectangle comes from Windows, and it does not match with our calculations for scaling controls by AutoscaleFactor.
Expand Down Expand Up @@ -1491,6 +1498,9 @@ internal void ScaleContainerForDpi(int deviceDpiNew, int deviceDpiOld, Rectangle
// We want to perform layout for dpi-changed high Dpi improvements - setting the second parameter to 'true'
ResumeAllLayout(this, true);
_isScaledByDpiChangedEvent = false;

// Scaling and ResumeLayout, due to DPI changed event, should be finished by now for this container.
_dpiScalingInProgress = false;
}
}

Expand Down
11 changes: 4 additions & 7 deletions src/System.Windows.Forms/src/System/Windows/Forms/Control.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1713,10 +1713,10 @@ internal bool IsTopMdiWindowClosing
}

/// <summary>
/// returns bool indicating whether the control is currently being scaled.
/// Returns bool indicating whether the control is currently being scaled.
/// This property is set in ScaleControl method to allow method being called to condition code that should not run for scaling.
/// </summary>
internal bool IsCurrentlyBeingScaled
internal bool ScalingInProgress
{
get => GetExtendedState(ExtendedStates.CurrentlyBeingScaled);
private set => SetExtendedState(ExtendedStates.CurrentlyBeingScaled, value);
Expand Down Expand Up @@ -10450,7 +10450,7 @@ internal void ScaleControl(SizeF includedFactor, SizeF excludedFactor, Control r
{
try
{
IsCurrentlyBeingScaled = true;
ScalingInProgress = true;

BoundsSpecified includedSpecified = BoundsSpecified.None;
BoundsSpecified excludedSpecified = BoundsSpecified.None;
Expand Down Expand Up @@ -10489,7 +10489,7 @@ internal void ScaleControl(SizeF includedFactor, SizeF excludedFactor, Control r
}
finally
{
IsCurrentlyBeingScaled = false;
ScalingInProgress = false;
}
}

Expand Down Expand Up @@ -10589,9 +10589,6 @@ protected virtual void ScaleControl(SizeF factor, BoundsSpecified specified)
scaledSize = LayoutUtils.UnionSizes(scaledSize, minSize);

if (DpiHelper.IsScalingRequirementMet
// In the v2 layout, anchors are updated/computed after the controls bounds changed
// and, thus, don't need scaling.
&& !DefaultLayout.UseAnchorLayoutV2(this)
&& ParentInternal is { } parent
&& (parent.LayoutEngine == DefaultLayout.Instance))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,12 @@ internal static void UpdateAnchorInfoV2(Control control)
return;
}

// Anchors are already scaled for the new DPI.
if (DpiScalingInProgress(control, parent))
{
return;
}

AnchorInfo anchorInfo = GetAnchorInfo(control);
if (anchorInfo is null)
{
Expand All @@ -913,6 +919,28 @@ internal static void UpdateAnchorInfoV2(Control control)

anchorInfo.Right = displayRect.Width - (x + elementBounds.Width);
anchorInfo.Bottom = displayRect.Height - (y + elementBounds.Height);

// Walk through parent hierarchy and check if scaling due to DPI change is in progress.
static bool DpiScalingInProgress(Control control, Control parent)
{
if (control.ScalingInProgress
|| (control is ContainerControl container && container._dpiScalingInProgress))
{
return true;
}

while (parent is not null)
{
if (parent is ContainerControl parentContainer && parentContainer._dpiScalingInProgress)
{
return true;
}

parent = parent.Parent;
}

return false;
}
}

public static AnchorStyles GetAnchor(IArrangedElement element) => CommonProperties.xGetAnchor(element);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1756,7 +1756,7 @@ protected override void SetBoundsCore(int x, int y, int width, int height, Bound

// Second argument to GetPreferredWidth and GetPreferredHeight is a boolean specifying if we should update the number of rows/columns.
// We only want to update the number of rows/columns if we are not currently being scaled.
bool updateRowsAndColumns = !DpiHelper.IsScalingRequirementMet || !IsCurrentlyBeingScaled;
bool updateRowsAndColumns = !DpiHelper.IsScalingRequirementMet || !ScalingInProgress;

if (width != oldBounds.Width)
{
Expand Down