Controls

Border

Border is a single-child chrome wrapper. It paints a background across its full layout slot, draws rectangular border edges on each side, and adds border thickness plus padding around the hosted child element.

Quick start

Use Border when you need simple container chrome around exactly one child element. It is a common building block for cards, section headers, framed content, and control templates.

Minimal border

<Border Background="#223245"
        BorderBrush="#4FC7C1"
        BorderThickness="1" />

Bordered card with content

<Border Background="#182636"
        BorderBrush="#28445F"
        BorderThickness="1"
        Padding="12">
  <TextBlock Text="Connection established." />
</Border>

Asymmetric chrome for layout framing

<Border Background="#101822"
        BorderBrush="#3E5670"
        BorderThickness="1,1,1,3"
        Padding="16,10,16,14">
  <StackPanel>
    <TextBlock Text="Build summary" Margin="0,0,0,6" />
    <TextBlock Text="3 warnings, 0 errors" />
  </StackPanel>
</Border>

Default recommendation: treat Border as a lightweight layout and styling primitive. If you need multiple children directly, put a panel such as Grid or StackPanel inside the border.

How Border lays out its child

Border adds chrome thickness around its child during both measure and arrange. The total chrome is the sum of BorderThickness and Padding for each side.

Measure

During measure, Border subtracts the combined border and padding from the available size before measuring its child. Its desired size is the child desired size plus that combined chrome.

Arrange

During arrange, the child is placed inside the inner rectangle after subtracting left, top, right, and bottom chrome from the final slot.

  • Desired width = child desired width + left/right border thickness + left/right padding.
  • Desired height = child desired height + top/bottom border thickness + top/bottom padding.
  • If no child is present, desired size is just the combined border and padding thickness.
  • If the final slot is too small, the child is arranged in the remaining non-negative inner rectangle.
<Border BorderBrush="#55738F"
        BorderThickness="2"
        Padding="12,8">
  <TextBlock Text="Measured content" />
</Border>

In that example, the child gets the available size reduced by 2 + 12 on the left, 2 + 8 on the top, and the corresponding values on the other sides.

Rendering behavior

The render path is intentionally simple and predictable. Border does not draw rounded geometry or perform clipping. It paints axis-aligned rectangles.

Background fill

Background fills the entire layout slot first, including the space underneath the border edges.

Edge rendering

Each side of the border is then drawn as a separate filled rectangle using BorderBrush and the corresponding thickness value.

Opacity

The element's normal Opacity participates in rendering, so background and edge rectangles are tinted by the current opacity value.

  • Left, right, top, and bottom borders are rendered independently.
  • A side is skipped when its thickness is less than or equal to zero.
  • Border edges remain rectangular even if CornerRadius is set.
<Border Background="#20405C"
        BorderBrush="#9AD1FF"
        BorderThickness="4,1,1,1"
        Opacity="0.85">
  <TextBlock Text="Accent rail on the left" Margin="8" />
</Border>

Single-child content model

Border hosts exactly one child element. The XAML loader has explicit support for this and throws if you place multiple direct children inside the same border.

Correct

Put one element inside the border. If you need more, place a panel inside the border and add the rest under that panel.

Incorrect

Do not place two sibling elements directly under the border. That violates the supported XAML content model.

Single child with nested layout

<Border Background="#16212D"
        BorderBrush="#34506C"
        BorderThickness="1"
        Padding="12">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <TextBlock Grid.Row="0" Text="Account" Margin="0,0,0,6" />
    <TextBlock Grid.Row="1" Text="Signed in as admin@example.com" />
  </Grid>
</Border>

Explicit property-element form

<Border BorderBrush="#28445F" BorderThickness="1">
  <Border.Child>
    <TextBlock Text="Hosted through Border.Child" />
  </Border.Child>
</Border>

Loader contract: the framework's XAML loader handles Border directly and enforces the single-child rule with a dedicated error message when more than one visual child is supplied.

Property reference

Chrome properties

Background: a Color value used to fill the full layout slot.

BorderBrush: a Color value used for all rendered border edges.

BorderThickness: a Thickness that controls the size of each border side and contributes to measure/arrange.

Padding: a Thickness inside the border that adds inner space around the child and contributes to measure/arrange.

Content and shape

Child: the single hosted UIElement.

CornerRadius: a Thickness property exposed by the API, but the current render path does not use it.

Opacity: inherited from the element base classes and applied during rendering.

Use color literals such as #223245, named colors when supported by the loader, or bound values that resolve to Color. Do not document or expect WPF-style brush objects for Background or BorderBrush on this control.

Patterns and examples

Card or panel container

<Border Background="#172331"
        BorderBrush="#28445F"
        BorderThickness="1"
        Padding="14">
  <StackPanel>
    <TextBlock Text="Recent sessions" Margin="0,0,0,10" />
    <TextBlock Text="12 sessions loaded" />
  </StackPanel>
</Border>

Section header

<Border Background="#203040"
        BorderBrush="#4A6C89"
        BorderThickness="0,0,0,1"
        Padding="0,0,0,8">
  <TextBlock Text="Diagnostics" />
</Border>

Status badge or chip

<Border Background="#1D3A2A"
        BorderBrush="#4BA36E"
        BorderThickness="1"
        Padding="8,4">
  <TextBlock Text="ONLINE" />
</Border>

Input or content frame

<Border Background="#111922"
        BorderBrush="#35516B"
        BorderThickness="1"
        Padding="10">
  <TextBox Text="{Binding SearchText}" Width="220" />
</Border>

Nested borders for layered chrome

<Border Background="#0E141C"
        BorderBrush="#2C4259"
        BorderThickness="1"
        Padding="6">
  <Border Background="#172331"
          BorderBrush="#4F6E8C"
          BorderThickness="1"
          Padding="12">
    <TextBlock Text="Two-stage framing" />
  </Border>
</Border>

Border inside a ControlTemplate

<Style x:Key="PanelButtonStyle" TargetType="{x:Type Button}">
  <Setter Property="Background" Value="#223245" />
  <Setter Property="BorderBrush" Value="#4FC7C1" />
  <Setter Property="BorderThickness" Value="1" />
  <Setter Property="Padding" Value="14,8" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Button}">
        <Border Background="{TemplateBinding Background}"
                BorderBrush="{TemplateBinding BorderBrush}"
                BorderThickness="{TemplateBinding BorderThickness}"
                Padding="{TemplateBinding Padding}">
          <ContentPresenter HorizontalAlignment="Center"
                            VerticalAlignment="Center" />
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Notes and pitfalls

Background and BorderBrush are colors, not brushes. Use values that resolve to Color. Examples and styles should not imply WPF brush semantics for this control.

CornerRadius is currently a no-op for rendering. The property exists on the API surface, but the current OnRender implementation still draws rectangular edges and background fills.

No implicit clipping. Border adds chrome and spacing, but it is not a general clipping primitive and does not automatically clip child content to a rounded or custom shape.

Use a panel for multiple elements. If you need more than one visual child, host a Grid, StackPanel, or another container inside the border instead of placing multiple direct children under it.