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
@@ -0,0 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections;

namespace System.Windows.Forms.Design;

/// <summary>
/// Helpers for adapting between generic and non-generic lists.
/// </summary>
internal static class AdapterHelpers
{
/// <summary>
/// Provides an extension method to safely extract the underlying non-generic <see cref="IList"/>
/// from a wrapped <see cref="IList&lt;T&gt;"/> when available.
/// </summary>
/// <typeparam name="T">The type of elements in the <see cref="IList&lt;T&gt;"/>.</typeparam>
/// <param name="list">The IList&lt;T&gt; to unwrap.</param>
/// <returns>The underlying non-generic <see cref="IList"/> if available; otherwise, the original <see cref="IList&lt;T&gt;"/>.</returns>
internal static IList Unwrap<T>(this IList<T> list) => list is IWrapper<IList> wrapper ? wrapper.Unwrap() : (IList)list;

/// <summary>
/// Provides an extension method to adapt a non-generic IList to a generic <see cref="IList&lt;T&gt;"/> by creating
/// a <see cref="ListAdapter&lt;T&gt;"/> when needed.
/// </summary>
/// <typeparam name="T">The desired type of elements in the resulting <see cref="IList&lt;T&gt;"/>.</typeparam>
/// <param name="list">The non-generic <see cref="IList"/> to adapt.</param>
/// <returns>
/// A generic <see cref="IList&lt;T&gt;"/> if the input IList can be cast to <see cref="IList&lt;T&gt;"/> otherwise, a new <see cref="ListAdapter&lt;T&gt;"/> wrapping the input IList.
/// </returns>
internal static IList<T> Adapt<T>(this IList list) => list is IList<T> iList ? iList : new ListAdapter<T>(list);
}
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ private void TestHook_GetAllSnapLines(ref Message m)

if (host.GetDesigner(comp) is ControlDesigner designer)
{
foreach (SnapLine line in designer.SnapLines)
foreach (SnapLine line in designer.SnapLinesInternal)
{
snapLineInfo.Append($"{line}\tAssociated Control = {designer.Control.Name}:::");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ internal DragAssistanceManager(IServiceProvider serviceProvider, Graphics graphi
/// </summary>
private void AddSnapLines(ControlDesigner controlDesigner, List<SnapLine> horizontalList, List<SnapLine> verticalList, bool isTarget, bool validTarget)
{
IList snapLines = controlDesigner.SnapLines;
IList<SnapLine> snapLines = controlDesigner.SnapLinesInternal;
// Used for padding snaplines
Rectangle controlRect = controlDesigner.Control.ClientRectangle;
// Used for all others
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public override IList SnapLines
{
get
{
ArrayList snapLines = base.SnapLines as ArrayList;
IList<SnapLine> snapLines = SnapLinesInternal;
FlatStyle flatStyle = FlatStyle.Standard;
ContentAlignment alignment = ContentAlignment.MiddleCenter;

Expand Down Expand Up @@ -103,7 +103,7 @@ public override IList SnapLines

snapLines.Add(new SnapLine(SnapLineType.Baseline, baseline, SnapLinePriority.Medium));

return snapLines;
return snapLines.Unwrap();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ public override IList SnapLines
{
get
{
ArrayList snapLines = base.SnapLines as ArrayList;
IList<SnapLine> snapLines = SnapLinesInternal;

// a single text-baseline for the label (and linklabel) control
int baseline = DesignerUtils.GetTextBaseline(Control, Drawing.ContentAlignment.TopLeft);
baseline += 3;
snapLines.Add(new SnapLine(SnapLineType.Baseline, baseline, SnapLinePriority.Medium));

return snapLines;
return snapLines.Unwrap();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,13 +356,15 @@ private bool IsResizableConsiderAutoSize(PropertyDescriptor autoSizeProp, Proper
/// Returns a list of SnapLine objects representing interesting alignment points for this control.
/// These SnapLines are used to assist in the positioning of the control on a parent's surface.
/// </summary>
public virtual IList SnapLines => SnapLinesInternal();
public virtual IList SnapLines => EdgeAndMarginSnapLines().Unwrap();

internal IList SnapLinesInternal() => SnapLinesInternal(Control.Margin);
internal IList<SnapLine> SnapLinesInternal => SnapLines.Adapt<SnapLine>();

internal IList SnapLinesInternal(Padding margin)
internal IList<SnapLine> EdgeAndMarginSnapLines() => EdgeAndMarginSnapLines(Control.Margin);

internal IList<SnapLine> EdgeAndMarginSnapLines(Padding margin)
{
ArrayList snapLines = new(4);
List<SnapLine> snapLines = new(8);
int width = Control.Width;
int height = Control.Height;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public override IList SnapLines
{
get
{
IList snapLines = base.SnapLines;
IList<SnapLine> snapLines = SnapLinesInternal;

// A single text-baseline for the label (and linklabel) control.
int baseline = DesignerUtils.GetTextBaseline(Control, ContentAlignment.MiddleLeft);
Expand All @@ -30,7 +30,7 @@ public override IList SnapLines
baseline += 2;
snapLines.Add(new SnapLine(SnapLineType.Baseline, baseline, SnapLinePriority.Medium));

return snapLines;
return snapLines.Unwrap();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure annotating FlowPanelDesigner for NRT should be part of this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure? Its a very small change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I though the parent class wasn't annotated, but apparently it is, so in that light it's a small change (though the parent's parent isn't, which exposes us to incorrect assumptions)


using System.Collections;
using System.Windows.Forms.Design.Behavior;

Expand All @@ -16,25 +14,19 @@ public override IList SnapLines
{
get
{
ArrayList snapLines = (ArrayList)base.SnapLines;
IList<SnapLine> snapLines = SnapLinesInternal;

// identify all the paddings to remove
ArrayList paddingsToRemove = new(4);
foreach (SnapLine line in snapLines)
// identify and remove all paddings
for (int i = snapLines.Count - 1; i >= 0; i--)
{
if (line.Filter is not null && line.Filter.Contains(SnapLine.Padding))
if (snapLines[i] is SnapLine line
&& line.Filter?.Contains(SnapLine.Padding) == true)
{
paddingsToRemove.Add(line);
snapLines.RemoveAt(i);
}
}

// remove all padding
foreach (SnapLine line in paddingsToRemove)
{
snapLines.Remove(line);
}

return snapLines;
return snapLines.Unwrap();
}
}

Expand All @@ -48,7 +40,7 @@ protected override void OnDragDrop(DragEventArgs de)
{
base.OnDragDrop(de);

SelectionManager sm = GetService(typeof(SelectionManager)) as SelectionManager;
SelectionManager? sm = GetService(typeof(SelectionManager)) as SelectionManager;
sm?.Refresh();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,12 @@ public override IList SnapLines
{
get
{
ArrayList snapLines = null;
IList<SnapLine> snapLines = null;
AddPaddingSnapLines(ref snapLines);
if (snapLines is null)
{
Debug.Fail("why did base.AddPaddingSnapLines return null?");
snapLines = new ArrayList(4);
snapLines = new List<SnapLine>(4);
}

// if the padding has not been set - then we'll auto-add padding to form - this is a Usability request
Expand Down Expand Up @@ -218,7 +218,7 @@ public override IList SnapLines
}
}

return snapLines;
return (IList)snapLines;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Windows.Forms.Design;

/// <summary>
/// Interface to provide a contract to provide access to the underlying type.
/// </summary>
/// <typeparam name="T">The type of object being wrapped.</typeparam>
internal interface IWrapper<T>
{
T Unwrap();
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public override IList SnapLines
{
get
{
ArrayList snapLines = base.SnapLines as ArrayList;
IList<SnapLine> snapLines = SnapLinesInternal;
ContentAlignment alignment = ContentAlignment.TopLeft;

PropertyDescriptor prop;
Expand Down Expand Up @@ -93,7 +93,7 @@ public override IList SnapLines
}
}

return snapLines;
return snapLines.Unwrap();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections;

namespace System.Windows.Forms.Design;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a blank line and comments for the class


/// <summary>
/// Adapter for bridging between generic and non-generic lists.
/// It implements both the generic <see cref="IList&lt;T&gt;"/> and the non-generic
/// <see cref="IWrapper&lt;IList&gt;"/> interfaces
/// to provide a unified interface for working with IList collections.
/// </summary>
/// <typeparam name="T">The type of elements in the list.</typeparam>
internal sealed class ListAdapter<T> : IList<T>, IWrapper<IList>
{
private readonly IList _list;
internal ListAdapter(IList list) => _list = list.OrThrowIfNull();

T IList<T>.this[int index]
{
get => (T?)_list[index] ?? throw new InvalidOperationException();
set => _list[index] = value.OrThrowIfNull();
}

int ICollection<T>.Count => _list.Count;

bool ICollection<T>.IsReadOnly => _list.IsReadOnly;

void ICollection<T>.Add(T item) => _list.Add(item.OrThrowIfNull());
void ICollection<T>.Clear() => _list.Clear();
bool ICollection<T>.Contains(T item) => _list.Contains(item);
void ICollection<T>.CopyTo(T[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
int IList<T>.IndexOf(T item) => _list.IndexOf(item);
void IList<T>.Insert(int index, T item) => _list.Insert(index, item.OrThrowIfNull());
void IList<T>.RemoveAt(int index) => _list.RemoveAt(index);

bool ICollection<T>.Remove(T item)
{
if (_list.IsReadOnly || !_list.Contains(item))
{
return false;
}

_list.Remove(item);
return true;
}

IEnumerator<T> IEnumerable<T>.GetEnumerator() => new Enumerator(_list.GetEnumerator());

private sealed class Enumerator(IEnumerator _enumerator) : IEnumerator<T>
{
T IEnumerator<T>.Current => (T)_enumerator.Current;
object IEnumerator.Current => _enumerator.Current;

void IDisposable.Dispose() { }
bool IEnumerator.MoveNext() => _enumerator.MoveNext();
void IEnumerator.Reset() => _enumerator.Reset();
}

public IList Unwrap() => _list;
}
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,13 @@ protected Size GridSize
// We need to allocation new ArrayList and pass it to the caller..
// So its ok to Suppress this.
protected void AddPaddingSnapLines(ref ArrayList snapLines)
{
snapLines ??= new ArrayList(4);
=> AddPaddingSnapLinesCommon((snapLines ??= new(4)).Adapt<SnapLine>());

internal void AddPaddingSnapLines(ref IList<SnapLine> snapLines)
=> AddPaddingSnapLinesCommon(snapLines ??= new List<SnapLine>(4));

private void AddPaddingSnapLinesCommon(IList<SnapLine> snapLines)
{
// In order to add padding, we need to get the offset from the usable client area of our control
// and the actual origin of our control. In other words: how big is the non-client area here?
// Ex: we want to add padding on a form to the insides of the borders and below the titlebar.
Expand Down Expand Up @@ -328,16 +332,16 @@ public override IList SnapLines
{
get
{
ArrayList snapLines = base.SnapLines as ArrayList;
IList<SnapLine> snapLines = SnapLinesInternal;

if (snapLines is null)
{
Debug.Fail("why did base.SnapLines return null?");
snapLines = new ArrayList(4);
snapLines = new List<SnapLine>(4);
}

AddPaddingSnapLines(ref snapLines);
return snapLines;
return snapLines.Unwrap();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ internal partial class SplitContainerDesigner : ParentControlDesigner
/// </summary>
public override IList SnapLines =>
// We don't want padding snaplines, so call directly to the internal method.
SnapLinesInternal();
EdgeAndMarginSnapLines().Unwrap();

/// <summary>
/// Returns the number of internal control designers in the <see cref="SplitContainerDesigner"/>. An internal control is a control that is not in the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,10 @@ public override IList SnapLines
{
int baseline = DesignerUtils.GetTextBaseline(Control, Drawing.ContentAlignment.TopLeft);

BorderStyle borderStyle = BorderStyle.Fixed3D;
PropertyDescriptor? prop = TypeDescriptor.GetProperties(Component)["BorderStyle"];
if (prop is not null)
{
borderStyle = (BorderStyle)prop.GetValue(Component)!;
}
BorderStyle borderStyle = prop is not null
? (BorderStyle)prop.GetValue(Component)!
: BorderStyle.Fixed3D;

if (borderStyle == BorderStyle.None)
{
Expand All @@ -53,11 +51,9 @@ public override IList SnapLines
baseline += 0;
}

IList snapLines = base.SnapLines;

IList<SnapLine> snapLines = SnapLinesInternal;
snapLines.Add(new SnapLine(SnapLineType.Baseline, baseline, SnapLinePriority.Medium));

return snapLines;
return snapLines.Unwrap();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public override DesignerActionListCollection ActionLists

public override IList SnapLines
// We don't want padding SnapLines, so call directly to the internal method.
=> SnapLinesInternal();
=> EdgeAndMarginSnapLines().Unwrap();

/// <summary>
/// Returns the internal control designer with the specified index in the ControlDesigner.
Expand Down
Loading