understanding-wpf-content-model
2
总安装量
1
周安装量
#68305
全站排名
安装命令
npx skills add https://github.com/christian289/dotnet-with-claudecode --skill understanding-wpf-content-model
Agent 安装分布
amp
1
cline
1
opencode
1
cursor
1
continue
1
kimi-cli
1
Skill 文档
WPF Content Model Patterns
WPF controls are classified into 4 main models based on how they contain content.
1. Content Model Hierarchy
Control
âââ ContentControl (Single Content)
â âââ Button
â âââ Label
â âââ CheckBox
â âââ RadioButton
â âââ ToolTip
â âââ ScrollViewer
â âââ UserControl
â âââ Window
â âââ HeaderedContentControl (Content + Header)
â âââ Expander
â âââ GroupBox
â âââ TabItem
â
âââ ItemsControl (Multiple Items)
âââ ListBox
âââ ComboBox
âââ ListView
âââ TreeView
âââ Menu
âââ TabControl
âââ HeaderedItemsControl (Items + Header)
âââ MenuItem
âââ TreeViewItem
âââ ToolBar
2. ContentControl
2.1 Characteristics
- Single Content property: Holds only one child element
- Content type: object (allows all types)
- ContentTemplate: Specifies how Content is rendered
2.2 Basic Usage
<!-- String content -->
<Button Content="Click Me"/>
<!-- Complex content -->
<Button>
<StackPanel Orientation="Horizontal">
<Image Source="/icon.png" Width="16"/>
<TextBlock Text="Save" Margin="5,0,0,0"/>
</StackPanel>
</Button>
2.3 Using ContentTemplate
<Button Content="Download">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Path Data="M12,2L12,14L8,10L12,14L16,10L12,14"
Fill="White" Width="16"/>
<TextBlock Text="{Binding}" Margin="5,0,0,0"/>
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
2.4 Creating ContentControl-Derived Controls
namespace MyApp.Controls;
using System.Windows;
using System.Windows.Controls;
/// <summary>
/// Card control that displays single content
/// </summary>
public sealed class CardControl : ContentControl
{
static CardControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(CardControl),
new FrameworkPropertyMetadata(typeof(CardControl)));
}
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register(
nameof(CornerRadius),
typeof(CornerRadius),
typeof(CardControl),
new PropertyMetadata(new CornerRadius(8)));
public CornerRadius CornerRadius
{
get => (CornerRadius)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
}
3. ItemsControl
3.1 Characteristics
- Items collection: Holds multiple child elements
- ItemsSource: Source for data binding
- ItemTemplate: Rendering method for each item
- ItemsPanel: Specifies the panel for item layout
3.2 Basic Usage
<!-- Direct item addition -->
<ListBox>
<ListBoxItem Content="Item 1"/>
<ListBoxItem Content="Item 2"/>
<ListBoxItem Content="Item 3"/>
</ListBox>
<!-- Data binding -->
<ListBox ItemsSource="{Binding Products}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" FontWeight="Bold"/>
<TextBlock Text="{Binding Price, StringFormat=${0:N2}}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
3.3 Customizing ItemsPanel
<!-- Horizontal list layout -->
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<!-- Grid layout -->
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<!-- Virtualized panel (large data) -->
<ListBox ItemsSource="{Binding LargeCollection}"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
3.4 Creating ItemsControl-Derived Controls
namespace MyApp.Controls;
using System.Windows;
using System.Windows.Controls;
/// <summary>
/// Control that displays a list of tags
/// </summary>
public sealed class TagListControl : ItemsControl
{
static TagListControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(TagListControl),
new FrameworkPropertyMetadata(typeof(TagListControl)));
}
protected override DependencyObject GetContainerForItemOverride()
{
// Specify container that wraps each item
return new TagItem();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is TagItem;
}
}
public sealed class TagItem : ContentControl
{
static TagItem()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(TagItem),
new FrameworkPropertyMetadata(typeof(TagItem)));
}
}
4. HeaderedContentControl
4.1 Characteristics
- Header + Content: Two separate regions
- HeaderTemplate: Header rendering method
- ContentTemplate: Content rendering method
4.2 Representative Controls
<!-- GroupBox -->
<GroupBox Header="Settings">
<StackPanel>
<CheckBox Content="Option 1"/>
<CheckBox Content="Option 2"/>
</StackPanel>
</GroupBox>
<!-- Expander -->
<Expander Header="Details" IsExpanded="False">
<TextBlock Text="Content not visible when collapsed"/>
</Expander>
<!-- TabItem -->
<TabControl>
<TabItem Header="Tab 1">
<TextBlock Text="Tab 1 content"/>
</TabItem>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Ellipse Width="8" Height="8" Fill="Green"/>
<TextBlock Text="Status" Margin="5,0,0,0"/>
</StackPanel>
</TabItem.Header>
<TextBlock Text="Tab 2 content"/>
</TabItem>
</TabControl>
4.3 Creating HeaderedContentControl-Derived Controls
namespace MyApp.Controls;
using System.Windows;
using System.Windows.Controls;
/// <summary>
/// Collapsible section control
/// </summary>
public sealed class CollapsibleSection : HeaderedContentControl
{
static CollapsibleSection()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(CollapsibleSection),
new FrameworkPropertyMetadata(typeof(CollapsibleSection)));
}
public static readonly DependencyProperty IsExpandedProperty =
DependencyProperty.Register(
nameof(IsExpanded),
typeof(bool),
typeof(CollapsibleSection),
new PropertyMetadata(true));
public bool IsExpanded
{
get => (bool)GetValue(IsExpandedProperty);
set => SetValue(IsExpandedProperty, value);
}
}
5. HeaderedItemsControl
5.1 Characteristics
- Header + Items: Header and multiple items
- Suitable for representing hierarchical structures
5.2 Representative Controls
<!-- TreeViewItem -->
<TreeView>
<TreeViewItem Header="Folder 1">
<TreeViewItem Header="File 1.txt"/>
<TreeViewItem Header="File 2.txt"/>
<TreeViewItem Header="Subfolder">
<TreeViewItem Header="File 3.txt"/>
</TreeViewItem>
</TreeViewItem>
</TreeView>
<!-- MenuItem -->
<Menu>
<MenuItem Header="File">
<MenuItem Header="New"/>
<MenuItem Header="Open"/>
<Separator/>
<MenuItem Header="Recent Files">
<MenuItem Header="file1.txt"/>
<MenuItem Header="file2.txt"/>
</MenuItem>
</MenuItem>
</Menu>
5.3 HierarchicalDataTemplate (Hierarchical Data Binding)
<TreeView ItemsSource="{Binding RootNodes}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Icon}" Width="16"/>
<TextBlock Text="{Binding Name}" Margin="5,0,0,0"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
6. Control Selection Guide
| Scenario | Recommended Base Class |
|---|---|
| Display single content | ContentControl |
| Single content + title | HeaderedContentControl |
| Display list/collection | ItemsControl |
| Selectable list | Selector (ListBox, ComboBox) |
| Hierarchical data | HeaderedItemsControl |
| Input field | TextBoxBase |
| Range value selection | RangeBase |
7. Content Property Processing Flow
Content Set
â
ContentTemplate exists?
âââ Yes â Render with DataTemplate
âââ No â Check Content type
âââ UIElement â Render directly
âââ String â Render with TextBlock
âââ Other â ToString() then TextBlock