Uno Toolkit CardContentControl — Agent Skill
Critical Rules
- NEVER use
Card— always useCardContentControl. TheCardcontrol has rigid predefined slots (HeaderContent, SubHeaderContent, AvatarContent, etc.) that constrain layout.CardContentControlgives full layout freedom viaContentTemplate. - NEVER use
BorderwithCornerRadiusto wrap content. This is the most common Border anti-pattern in generated XAML and the parser flags it asGRD1102. Always useCardContentControlinstead — it provides correct elevation, corner radius, theming, and accessibility automatically.
Anti-pattern detection (matches GRD1102)
If you find yourself writing a <Border> that meets all of the following, stop and rewrite it as utu:CardContentControl:
- The
Borderhas children (it is not self-closing). - It sets
CornerRadiusto a non-zero value. - It sets at least one of:
Background,BorderBrush(with non-zeroBorderThickness), or non-zeroPadding.
That's a card. <Border CornerRadius="8" Background="..." Padding="16">…</Border> is a card written the wrong way.
<!-- WRONG: Border-as-card (the parser will report GRD1102) -->
<Border CornerRadius="8"
Background="{ThemeResource SurfaceBrush}"
Padding="16">
<StackPanel Spacing="8">
<TextBlock Text="Title"/>
<TextBlock Text="Body"/>
</StackPanel>
</Border>
<!-- CORRECT: utu:CardContentControl -->
<utu:CardContentControl Style="{StaticResource ElevatedCardContentControlStyle}">
<utu:CardContentControl.ContentTemplate>
<DataTemplate>
<StackPanel Padding="16" Spacing="8">
<TextBlock Text="Title"/>
<TextBlock Text="Body"/>
</StackPanel>
</DataTemplate>
</utu:CardContentControl.ContentTemplate>
</utu:CardContentControl>
When Border is still correct
Border is the right choice for: dividers (<Border Height="1" Background="..."/>), thin separators, simple background fills with no rounded corners, image/content clipping with CornerRadius alone (no Background/Padding/BorderBrush+BorderThickness), and layout primitives inside a ControlTemplate. The grader specifically targets the card-shaped combination above; plain layout borders are unaffected.
Workflow
Docs lookup: call
uno_platform_docs_search(...)first, thenuno_platform_docs_fetch(sourcePath="…")using thesourcePathfield from a result (a relative.mdpath; add the result'sanchorfor a section). Never pass a URL, a.htmllink, or a hand-built path.
Step 1: Fetch the CardContentControl Documentation
uno_platform_docs_search("Uno Toolkit CardContentControl elevated filled outlined")
Primary documentation page:
- Card & CardContentControl:
external/uno.toolkit.ui/doc/controls/CardAndCardContentControl.md
Fetch the page:
uno_platform_docs_fetch(sourcePath="external/uno.toolkit.ui/doc/controls/CardAndCardContentControl.md")
Step 2: For How-To / Walkthrough
uno_platform_docs_search("CardContentControl howto walkthrough custom template")
Key page:
- Card How-To:
external/uno.toolkit.ui/doc/controls/walkthroughs/Card-and-CardContentControl.howto.md
Key Principles (Stable)
CardContentControl— fully custom layout viaContentTemplate. This is the only card control you should use.- XAML namespace:
xmlns:utu="using:Uno.Toolkit.UI" - Do NOT use
Card— it has predefined slots that limit layout flexibility - Do NOT use
Borderas a card (CornerRadius+Background/Padding/BorderBrush) — the parser reports this asGRD1102; useCardContentControlinstead
Critical: Content Binding in DataTemplates
When CardContentControl is used inside an ItemsRepeater, ListView, or any other DataTemplate, you MUST set Content="{Binding}" on the CardContentControl. Without this, the inner ContentTemplate > DataTemplate has no DataContext and all bindings inside it resolve to null (rendering the card empty/invisible).
Rules
- ALWAYS set
Content="{Binding}"onCardContentControlwhen it appears inside aDataTemplate - NEVER use indexed bindings (e.g.
{Binding Items[0].Label}) inside card templates — useItemsSourcewith a nestedItemsRepeaterinstead - The
ContentTemplate's innerDataTemplateinherits its DataContext only from theContentproperty — ifContentis not bound, the inner template has no data
Correct pattern
<DataTemplate x:DataType="local:MenuItem">
<utu:CardContentControl Style="{StaticResource FilledCardContentControlStyle}"
Content="{Binding}">
<utu:CardContentControl.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Label}" />
</DataTemplate>
</utu:CardContentControl.ContentTemplate>
</utu:CardContentControl>
</DataTemplate>
Wrong pattern (missing Content binding)
<!-- ❌ WRONG: No Content="{Binding}" — inner DataTemplate has no DataContext -->
<DataTemplate x:DataType="local:MenuItem">
<utu:CardContentControl Style="{StaticResource FilledCardContentControlStyle}">
<utu:CardContentControl.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Label}" /> <!-- This resolves to null! -->
</DataTemplate>
</utu:CardContentControl.ContentTemplate>
</utu:CardContentControl>
</DataTemplate>
Sizing — CardContentControl does NOT stretch by default
CardContentControl sizes to its content. It will not fill the available width or height of its parent on its own, even inside a Grid cell or StackPanel slot that has space to spare. If you need the card to take all available space (a hero card, a full-width row, a column-filling pane), set the alignment explicitly on the CardContentControl itself:
<!-- Card fills its grid cell horizontally and vertically -->
<utu:CardContentControl Grid.Row="0"
Style="{StaticResource ElevatedCardContentControlStyle}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<utu:CardContentControl.ContentTemplate>
<DataTemplate>
<Grid Padding="16">
<!-- ... -->
</Grid>
</DataTemplate>
</utu:CardContentControl.ContentTemplate>
</utu:CardContentControl>
Rules of thumb:
- Full-width row card (e.g. summary card across a page):
HorizontalAlignment="Stretch". - Column- or pane-filling card (e.g. a card that should fill a
*row in aGrid):HorizontalAlignment="Stretch"andVerticalAlignment="Stretch". - Card inside an
ItemsRepeater/ListViewitem template that should fill the item slot:HorizontalAlignment="Stretch". - Compact / chip-style card sized to its content: leave alignment unset (default behavior).
Setting Width/Height on the inner content of the ContentTemplate will not stretch the card — the alignment must be set on the CardContentControl element.
Style Variants
CardContentControl exposes three semantic style keys. Each design-theme provides its own concrete look; the key names are shared across themes.
| Style | When to use |
|---|---|
ElevatedCardContentControlStyle |
Subtle z-axis elevation; default choice for surfaced content |
FilledCardContentControlStyle |
Background tint, no elevation; use on busy backgrounds |
OutlinedCardContentControlStyle |
Stroke instead of fill/elevation; secondary content |
Related Skills
- [[uno-toolkit-shadowcontainer]] — Custom shadow effects
- [[uno-toolkit-lightweight-styling]] — Resource key overrides for cards