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
CornerRadiusis 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.