简体   繁体   English

如何在WPF自定义控件中显示基本控件

[英]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). (出于学习目的,这是一个愚蠢的示例)。

LabeledTextBox.cs LabeledTextBox.cs

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);
    }
}

Themes/Generic.xaml 主题/ Generic.xaml

<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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM