簡體   English   中英

如何在WPF自定義控件中顯示基本控件

[英]How to display the base control in a WPF custom control

我想擴展一個TextBox控件以包括一個Label,其中Label從我的自定義控件的Label屬性獲取其Content並自動附加到TextBox。 (出於學習目的,這是一個愚蠢的示例)。

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

主題/ 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>

我不知道如何顯示TextBox基類。 我已經搜索了SO和Google的前幾個鏈接。 看來我應該使用的是<ContentPresenter />但它根本沒有顯示出來。 我還嘗試了幾種將XAML中的ContentPresenter.ContentSource設置為無效的方法。

我知道我可以在ControlTemplate中添加一個TextBox,但這意味着要么丟失繼承的TextBox的所有屬性,要么需要手動附加它們的所有屬性,這使使用UserControl的自定義控件的全部目的無法實現。

只需將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>

您需要使用PART_ContentHost WPF magic訪問視覺元素:)

外觀如下:

<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