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,46 @@
// 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 System.Runtime.InteropServices;
using static Interop;

namespace System.Windows.Forms
{
public partial class Label
{
internal class LabelAccessibleObject : ControlAccessibleObject
{
private readonly Label _owningLabel;

public LabelAccessibleObject(Label owner) : base(owner)
{
_owningLabel = owner;
}

public override AccessibleRole Role
{
get
{
AccessibleRole role = _owningLabel.AccessibleRole;

if (role != AccessibleRole.Default)
{
return role;
}

return AccessibleRole.StaticText;
}
}

internal override object? GetPropertyValue(UiaCore.UIA propertyID)
=> propertyID switch
{
UiaCore.UIA.NamePropertyId => Name,
UiaCore.UIA.AutomationIdPropertyId => _owningLabel.Name,
UiaCore.UIA.ControlTypePropertyId => UiaCore.UIA.TextControlTypeId,
_ => base.GetPropertyValue(propertyID)
};
}
}
}
113 changes: 39 additions & 74 deletions src/System.Windows.Forms/src/System/Windows/Forms/Label.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace System.Windows.Forms
[ToolboxItem("System.Windows.Forms.Design.AutoSizeToolboxItem," + AssemblyRef.SystemDesign)]
[SRDescription(nameof(SR.DescriptionLabel))]
// If not for FormatControl, we could inherit from ButtonBase and get foreground images for free.
public class Label : Control, IAutomationLiveRegion
public partial class Label : Control, IAutomationLiveRegion
{
private static readonly object EVENT_TEXTALIGNCHANGED = new object();

Expand Down Expand Up @@ -1635,97 +1635,62 @@ protected override void WndProc(ref Message m)
}
}

internal class LabelAccessibleObject : ControlAccessibleObject
/// <summary>
/// Override ImageList.Indexer to support Label's ImageList semantics.
/// </summary>
internal class LabelImageIndexer : ImageList.Indexer
{
public LabelAccessibleObject(Label owner) : base(owner)
private readonly Label owner;
private bool useIntegerIndex = true;

public LabelImageIndexer(Label owner)
{
this.owner = owner;
}

public override AccessibleRole Role
public override ImageList ImageList
{
get
{
AccessibleRole role = Owner.AccessibleRole;
if (role != AccessibleRole.Default)
{
return role;
}
return AccessibleRole.StaticText;
}
get { return owner?.ImageList; }
set { Debug.Assert(false, "Setting the image list in this class is not supported"); }
}

internal override bool IsIAccessibleExSupported() => true;

internal override object GetPropertyValue(UiaCore.UIA propertyID)
public override string Key
{
switch (propertyID)
get => base.Key;
set
{
case UiaCore.UIA.NamePropertyId:
return Name;
case UiaCore.UIA.ControlTypePropertyId:
return UiaCore.UIA.TextControlTypeId;
base.Key = value;
useIntegerIndex = false;
}

return base.GetPropertyValue(propertyID);
}
}
}

/// <summary>
/// Override ImageList.Indexer to support Label's ImageList semantics.
/// </summary>
internal class LabelImageIndexer : ImageList.Indexer
{
private readonly Label owner;
private bool useIntegerIndex = true;

public LabelImageIndexer(Label owner)
{
this.owner = owner;
}

public override ImageList ImageList
{
get { return owner?.ImageList; }
set { Debug.Assert(false, "Setting the image list in this class is not supported"); }
}

public override string Key
{
get => base.Key;
set
{
base.Key = value;
useIntegerIndex = false;
}
}

public override int Index
{
get => base.Index;
set
public override int Index
{
base.Index = value;
useIntegerIndex = true;
get => base.Index;
set
{
base.Index = value;
useIntegerIndex = true;
}
}
}

public override int ActualIndex
{
get
public override int ActualIndex
{
if (useIntegerIndex)
{
// The behavior of label is to return the last item in the Images collection
// if the index is currently set higher than the count.
return (Index < ImageList.Images.Count) ? Index : ImageList.Images.Count - 1;
}
else if (ImageList != null)
get
{
return ImageList.Images.IndexOfKey(Key);
}
if (useIntegerIndex)
{
// The behavior of label is to return the last item in the Images collection
// if the index is currently set higher than the count.
return (Index < ImageList.Images.Count) ? Index : ImageList.Images.Count - 1;
}
else if (ImageList != null)
{
return ImageList.Images.IndexOfKey(Key);
}

return -1;
return -1;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,13 @@ public void Label_ImageKey_setting_empty_resets_ImageIndex()
Assert.Equal(-1, control.ImageIndex);
}

[WinFormsFact]
public void Label_SupportsUiaProviders_returns_true()
{
using var label = new Label();
Assert.True(label.SupportsUiaProviders);
}

public class SubLabel : Label
{
public new bool CanEnableIme => base.CanEnableIme;
Expand Down