带有内容周围控件的ContentControl
本文关键字:控件 ContentControl 周围 | 更新日期: 2023-09-27 18:03:45
我想在WPF中创建一个可以包含一个元素的自定义ContentControl
。这很简单,我做过很多次了。但是这里我想让内容控件的底部和左边都有标尺。我希望这些控件可以从后面的代码访问。我不知道该怎么走下去。我考虑了一个模板,但然后标尺控件将不容易访问。我还考虑过创建一个具有类似content的依赖属性的UserControl
,但是对于该控件的用户来说,XAML并不像使用内容控件那样简单。
谢谢。
可以使用模板部件。你可以在这个页面上看到一个完整的例子:
http://msdn.microsoft.com/en-us/library/ee330302 (v = vs.110) . aspx
从这个例子中,CustomControl
是如何声明模板部分的:
[TemplatePart(Name = "UpButtonElement", Type = typeof(RepeatButton))]
[...]
public class NumericUpDown : Control
[...]
以及如何访问它们:
public override void OnApplyTemplate()
{
UpButtonElement = GetTemplateChild("UpButton") as RepeatButton;
[...]
}
您所要求的是能够以常用的两种不同方式使用内容,但同时使用一个控件。你可以这样做,但只需要2个不同的内容属性。您可以定义自己的次要内容属性集,但从HeaderContentControl
派生要容易得多,它已经为您提供了Header
属性。
为了允许控件的用户像普通的ContentControl
一样对待它,并且只是将内容包含在标签中,您可以使用Header
内容作为您定义UserControl
样式的部分,并且可以从代码后访问。在该内容中,您可以在任何想要接收外部Content
的地方放置ContentPresenter
。然后你还需要调整ControlTemplate
,只显示Header
的内容(Content
将在Header
部分内,记住)。
<HeaderedContentControl x:Class="WpfApp.MyRulerControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp">
<HeaderedContentControl.Template>
<ControlTemplate TargetType="{x:Type local:MyRulerControl}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter ContentSource="Header"/>
</Border>
</ControlTemplate>
</HeaderedContentControl.Template>
<HeaderedContentControl.Header>
<StackPanel>
<Border x:Name="Ruler1" Height="20"/>
<ContentPresenter
Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MyRulerControl}}, Path=Content}"
ContentTemplate="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MyRulerControl}}, Path=ContentTemplate}"/>
<Border x:Name="Ruler2" Height="20"/>
</StackPanel>
</HeaderedContentControl.Header>
</HeaderedContentControl>
现在你可以像平常一样使用控件了:
<local:MyRulerControl>
<TextBlock Text="External content here"/>
</local:MyRulerControl>
您也可以从code-behind:
获取Header
部分中的任何内容。 public MyRulerControl()
{
InitializeComponent();
Ruler1.Background = Brushes.Red;
Ruler2.Background = Brushes.Blue;
}