[英]How to display the base control in a WPF custom control
I want to extend a TextBox control to include a Label, where the Label gets its Content
from my custom control's Label
property and automatically attaches to the TextBox. 我想扩展一个TextBox控件以包括一个Label,其中Label从我的自定义控件的Label
属性获取其Content
并自动附加到TextBox。 (This is a dumbed down example for learning purposes). (出于学习目的,这是一个愚蠢的示例)。
public class LabeledTextBox : TextBox
{
static LabeledTextBox() =>
DefaultStyleKeyProperty.OverrideMetadata(typeof(LabeledTextBox),
new FrameworkPropertyMetadata(typeof(LabeledTextBox)));
public static readonly DependencyProperty LabelProperty =
DependencyProperty.Register("Label", typeof(string), typeof(LabeledTextBox));
public string Label
{
get => (string)GetValue(LabelProperty);
set => SetValue(LabelProperty, value);
}
}
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyExample">
<Style TargetType="{x:Type local:LabeledTextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:LabeledTextBox}">
<StackPanel Orientation="Vertical">
<Label Margin="0 0 0 4" Content="{TemplateBinding Label}" Target="{Binding ElementName=tbThis}" />
<!-- This doesn't work -->
<ContentPresenter x:Name="tbThis" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
I can't figure out how to display the TextBox base class. 我不知道如何显示TextBox基类。 I've searched through SO and the first several links in Google. 我已经搜索了SO和Google的前几个链接。 It looks like what I should use is <ContentPresenter />
but it's simply not showing up. 看来我应该使用的是<ContentPresenter />
但它根本没有显示出来。 I also tried several variants of setting ContentPresenter.ContentSource
within the XAML to no avail. 我还尝试了几种将XAML中的ContentPresenter.ContentSource
设置为无效的方法。
I know I could add a TextBox in the ControlTemplate, but that would mean either losing all the properties of the inherited TextBox or needing to attach them all manually, which defeats the entire purpose of using a custom control over a UserControl
. 我知道我可以在ControlTemplate中添加一个TextBox,但这意味着要么丢失继承的TextBox的所有属性,要么需要手动附加它们的所有属性,这使使用UserControl
的自定义控件的全部目的无法实现。
Simply bind Target
to TemplatedParent
: 只需将Target
绑定到TemplatedParent
:
<ControlTemplate TargetType="{x:Type local:LabeledTextBox}">
<StackPanel>
<Label Target="{Binding RelativeSource={RelativeSource TemplatedParent}}" Content="{TemplateBinding Label}"/>
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer Focusable="False" x:Name="PART_ContentHost" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
</StackPanel>
</ControlTemplate>
You need to access the visual element using PART_ContentHost WPF magic :) 您需要使用PART_ContentHost WPF magic访问视觉元素:)
Here is how it would look: 外观如下:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyExample">
<Style TargetType="{x:Type local:LabeledTextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:LabeledTextBox}">
<StackPanel Orientation="Vertical">
<Label Margin="0 0 0 4" Content="{TemplateBinding Label}" Target="{Binding ElementName=tbThis}" />
<ScrollViewer x:Name="PART_ContentHost"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.