Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add unit tests
  • Loading branch information
dreddy-work committed Oct 26, 2022
commit b3c1bbeeafbb555e6abea2e09ff8eb7162d04d28
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace System.Windows.Forms.Primitives
internal static partial class LocalAppContextSwitches
{
private const string ScaleTopLevelFormMinMaxSizeForDpiSwitchName = "System.Windows.Forms.ScaleTopLevelFormMinMaxSizeForDpi";
private const string EnableImprovedAnchorLayoutSwitchName = "System.Windows.Forms.EnableImprovedAnchorLayout";
internal const string EnableImprovedAnchorLayoutSwitchName = "System.Windows.Forms.EnableImprovedAnchorLayout";

private static int s_scaleTopLevelFormMinMaxSizeForDpi;
private static int s_enableImprovedAnchorLayout;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -717,13 +717,6 @@ internal static void UpdateAnchorInfo(IArrangedElement element, bool enableImpro
return;
}

AnchorInfo anchorInfo = GetAnchorInfo(element);
if (anchorInfo is null)
{
anchorInfo = new AnchorInfo();
SetAnchorInfo(element, anchorInfo);
}

Debug.WriteLineIf(CompModSwitches.RichLayout.TraceInfo, "Update anchor info");
Debug.Indent();
Debug.WriteLineIf(CompModSwitches.RichLayout.TraceInfo, element.Container is null ? "No parent" : "Parent");
Expand All @@ -735,16 +728,23 @@ internal static void UpdateAnchorInfo(IArrangedElement element, bool enableImpro

if (enableImprovedAnchorLayout)
{
ComputeAnchorInfo(element, anchorInfo);
ComputeAnchorInfo(element);
}
else
{
ComputeLegacyAnchorInfo(element, anchorInfo);
ComputeLegacyAnchorInfo(element);
}
}

private static void ComputeLegacyAnchorInfo(IArrangedElement element, AnchorInfo anchorInfo)
private static void ComputeLegacyAnchorInfo(IArrangedElement element)
{
AnchorInfo anchorInfo = GetAnchorInfo(element);
if (anchorInfo is null)
{
anchorInfo = new AnchorInfo();
SetAnchorInfo(element, anchorInfo);
}

Rectangle bounds = GetCachedBounds(element);
AnchorInfo oldAnchorInfo = new AnchorInfo
{
Expand Down Expand Up @@ -833,8 +833,15 @@ private static void ComputeLegacyAnchorInfo(IArrangedElement element, AnchorInfo
Debug.Unindent();
}

private static void ComputeAnchorInfo(IArrangedElement element, AnchorInfo anchorInfo)
private static void ComputeAnchorInfo(IArrangedElement element)
{
AnchorInfo anchorInfo = GetAnchorInfo(element);
if (anchorInfo is null)
{
anchorInfo = new AnchorInfo();
SetAnchorInfo(element, anchorInfo);
}

Rectangle displayRect = element.Container.DisplayRectangle;
Rectangle elementBounds = element.Bounds;

Expand Down Expand Up @@ -1042,7 +1049,7 @@ private static void SetCachedBounds(IArrangedElement element, Rectangle bounds)
}
}

private static AnchorInfo GetAnchorInfo(IArrangedElement element)
internal static AnchorInfo GetAnchorInfo(IArrangedElement element)
{
return (AnchorInfo)element.Properties.GetObject(s_layoutInfoProperty);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Xunit;
using System.Drawing;
using System.Windows.Forms.Primitives;

namespace System.Windows.Forms.Layout.Tests
{
public class AnchorLayoutTests : IClassFixture<ThreadExceptionFixture>
{
private static (Form, Button) GetFormWithAnchoredButton()
{
Form form = new ();
form.Size = new Size(200, 300);
Button button = new ();
button.Location = new Point(20, 30);
button.Size = new Size(20, 30);
button.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;

return (form, button);
}

private static void Dispose(Form form, Button button)
{
button?.Dispose();
form?.Dispose();
}

[WinFormsFact]
public void ControlNotParented_NoAnchorsComputed()
{
var (form, button) = GetFormWithAnchoredButton();
DefaultLayout.AnchorInfo anchorInfo = DefaultLayout.GetAnchorInfo(button);
Assert.Null(anchorInfo);
_ = button.Handle; // Force handle creation;
Assert.Null(anchorInfo);
Dispose(form, button);
}

[WinFormsFact]
public void ControlHandleNotCreated_NoAnchorsComputed()
{
var (form, button) = GetFormWithAnchoredButton();
DefaultLayout.AnchorInfo anchorInfo = DefaultLayout.GetAnchorInfo(button);
Assert.Null(anchorInfo);
form.Controls.Add(button);
Assert.Null(anchorInfo);
Dispose(form, button);
}

[WinFormsFact]
public void ControlParentHandleNotCreated_NoAnchorsComputed()
{
var (form, button) = GetFormWithAnchoredButton();
DefaultLayout.AnchorInfo anchorInfo = DefaultLayout.GetAnchorInfo(button);
Assert.Null(anchorInfo);
_ = button.Handle; // Force handle creation;
form.Controls.Add(button);
Assert.Null(anchorInfo);
Dispose(form, button);
}

[WinFormsFact]
public void ConfigSwitchDisabled_NoHanldeCreated_AnchorsComputed()
{
AppContext.SetSwitch(LocalAppContextSwitches.EnableImprovedAnchorLayoutSwitchName, false);
var (form, button) = GetFormWithAnchoredButton();
form.Controls.Add(button);
DefaultLayout.AnchorInfo anchorInfo = DefaultLayout.GetAnchorInfo(button);
Assert.NotNull(anchorInfo);
Dispose(form, button);
}

[WinFormsTheory]
[InlineData(AnchorStyles.Top, 44, 30, 20, 30)]
[InlineData(AnchorStyles.Left, 20, 68, 20, 30)]
[InlineData(AnchorStyles.Right, 220, 68, 20, 30)]
[InlineData(AnchorStyles.Bottom, 44, 330, 20, 30)]
[InlineData(AnchorStyles.Top | AnchorStyles.Left, 20, 30, 20, 30)]
[InlineData(AnchorStyles.Top | AnchorStyles.Right, 220, 30, 20, 30)]
[InlineData(AnchorStyles.Top | AnchorStyles.Bottom, 44, 30, 20, 330)]
[InlineData(AnchorStyles.Left | AnchorStyles.Right, 20, 68, 220, 30)]
[InlineData(AnchorStyles.Bottom | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Left, 20, 30, 220, 330)]
public void ResizeAnchoredControlsParent_HanldeCreated_AnchorsApplied(AnchorStyles anchor, int x, int y, int width, int height)
{
AppContext.SetSwitch(LocalAppContextSwitches.EnableImprovedAnchorLayoutSwitchName, true);
var (form, button) = GetFormWithAnchoredButton();
button.Anchor = anchor;
DefaultLayout.AnchorInfo anchorInfo = DefaultLayout.GetAnchorInfo(button);
Assert.Null(anchorInfo);
form.Controls.Add(button);
form.Shown += OnFormShown;
form.ShowDialog();
Dispose(form, button);

void OnFormShown(object sender, EventArgs e)
{
Form formLocal = (Form)sender;
Control button1 = formLocal.Controls[0];

//Resize Form to compute button anchors.
formLocal.Size = new Size(400, 600);

Assert.Equal(x, button1.Bounds.X);
Assert.Equal(y, button1.Bounds.Y);
Assert.Equal(width, button1.Bounds.Width);
Assert.Equal(height, button1.Bounds.Height);
form.Close();
}
}
}
}