这是一个允许 UIElement 内容的 UserControl 示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Markup;
namespace TestClean.UserControls
{
[ContentProperty("Child")]
public partial class CustomBorder : UserControl
{
public static readonly DependencyProperty ChildProperty =
DependencyProperty.Register("Child", typeof(UIElement), typeof(CustomBorder), new UIPropertyMetadata(null));
public UIElement Child
{
get { return (UIElement)GetValue(ChildProperty); }
set { SetValue(ChildProperty, value); }
}
public CustomBorder()
{
InitializeComponent();
}
}
}
<UserControl x:Class="TestClean.UserControls.CustomBorder"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Name="control">
<Border BorderThickness="1" CornerRadius="10" BorderBrush="Red" Background="Pink" Padding="5">
<Border BorderThickness="1" CornerRadius="8" BorderBrush="Blue" Background="LightBlue" Padding="5">
<ContentPresenter Content="{Binding ElementName=control, Path=Child}" />
</Border>
</Border>
</UserControl>
使用示例:
<uc:CustomBorder>
<TextBlock Text="Lorem Ipsum"/>
</uc:CustomBorder>
看起来像:
随意修改边框即可。
编辑:要实际回答这个问题并在某种程度上重申我在对 Tim 的回答的评论中所说的话,UserControls 适合于此,因为它们直接封装了视觉表示并允许组合,同时不需要太多自定义逻辑(理论上它们可能非常复杂并且包含很多逻辑)。它们比 CustomControls 更轻量和更直接。
在 WPF 控件(即普通控件,包括仅从它们继承的 CustomControls)中被认为是无外观的,它们通常提供默认模板,但它们的关键方面是它们的功能,例如,如果您想到 ComboBox,它是一个包含项目的控件,它应该有一个或没有选定元素,并且应该有一个显示项目并支持选择等的下拉菜单。控件有责任提供构成此功能的必要属性和方法。由于这有时需要某些视觉元素才能存在,因此控件可以定义parts,它表示前端的最小接口。
看看Control Authoring overview,它更深入,可能比我能更好地解释很多事情。
另外:最终的轻量级方法是只使用模板:
<!-- You can use any resource dictionary, specifying it in App.xaml
simply makes it usable all over the application. -->
<Application.Resources>
<ControlTemplate x:Key="CustomBorderTemplate" TargetType="{x:Type ContentControl}">
<Border BorderThickness="1" CornerRadius="10" BorderBrush="Red" Background="Pink" Padding="5">
<Border BorderThickness="1" CornerRadius="8" BorderBrush="Blue" Background="LightBlue" Padding="5">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</Border>
</ControlTemplate>
</Application.Resources>
<ContentControl Template="{StaticResource CustomBorderTemplate}">
<TextBlock Text="Lorem Ipsum"/>
</ContentControl>
这会产生与 UserControl 相同的结果。