Vixen
dd8b0a81

LabeledContent

ui control Core/Vixen.Ui.Controls/Forms.cs:47
csharp
public sealed class LabeledContent

A caption, the control it names, and somewhere to say what went wrong.

Read the guide page for this →

Remarks

The row every form is made of, and the one shape this control set had no way to say. Doc 49 § 7.1 ranks LabeledContent beside GroupBox, Form and Section as rank 4 of the missing controls, and notes that Card and KeyValueList only approximate it. What they approximate is the picture; what none of them has is the join.

⚠ Two divs side by side is not this, and the difference is that a screen reader reads out an unnamed field. A TextBox, a NumericInput, a Slider and a Select all deliberately answer null to their native accessible name — a placeholder is a hint and a number is not a name — so a form of eight fields beside a column of words is eight unnamed fields, and nothing in the tree connects the two. PropertyGrid already knew this and writes the relation by hand for every row it builds (AddAccessibleRelation(LabelledBy, row.Label)); an application outside that grid had no way to. This control is that line, made the container's job so that it cannot be the caller's to forget.

⚠ And the message is a part rather than advice. TextField's own remarks say plainly that ValidationMessage is deliberately not written into the accessibility tree, because ARIA pairs aria-invalid with a separate element holding the words reached by aria-describedby — "the error text a form shows is a label somewhere in the layout". Description is that element, and the relation to it is written for the same reason the label's is.

⚠ A caption is clickable, which is the half a container cannot get from CSS. HTML's <label for> focuses its control on a click and every desktop toolkit does the same; a tick box with a three-word label beside it is a four-pixel target without it.

What it deliberately is not. It has no Required and computes no verdict: those belong to the field, which already reports both — mirroring them here would be a second copy of a fact, and FieldValidity's remarks say why the count of copies is the thing to keep at one. A row that wants an asterisk reads :required off its field with a sibling selector.

Fields and properties (12)

  • protected override string TagName

    The element name this type answers to when a caller does not choose one.

  • protected override bool AcceptsFocus
  • protected override AccessibleRole NativeRole
  • public UiElement Caption

    Where the caption is drawn.

  • public UiElement Content

    Where the field goes.

  • public UiElement Message

    Where the message under the field is drawn.

  • protected override UiElement ContentHost
  • public string? Label
  • public string? Description
  • public UiElement? Field

    The first thing in the row that can take the focus.

  • public static readonly UiPropertyKey LabelProperty

    Identity for Label.

  • public static readonly UiPropertyKey DescriptionProperty

    Identity for Description.

Methods (4)

  • protected override void OnCreated()

    Builds whatever this element is made of, once, as it joins a document.

  • public void Adopt(UiElement field)

    Joins a field in this row to the caption and the message.

  • public void ClearLabel()

    Unsets Label, so it takes its default or its ancestor's value again.

  • public void ClearDescription()

    Unsets Description, so it takes its default or its ancestor's value again.

Used by (3)

  • GalleryHelloUi
  • FieldContentVixen.Ui.Controls
  • LabeledContentTestsVixen.Ui.Controls.Tests