Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在WPF自定义控件中显示基控件_C#_Wpf_Xaml - Fatal编程技术网

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

C# 如何在WPF自定义控件中显示基控件,c#,wpf,xaml,C#,Wpf,Xaml,我想扩展TextBox控件以包含标签,标签从自定义控件的Label属性获取其内容并自动附加到TextBox。为了便于学习,这是一个简化的示例 LabeledTextBox.cs 公共类LabeledTextBox:TextBox { 静态标签文本框=> DefaultStyleKeyProperty.OverrideMetataTypeOfLabeledTextBox, 新的FrameworkPropertyMetadatatypeofLabeledTextBox; 公共静态只读Dependen

我想扩展TextBox控件以包含标签,标签从自定义控件的Label属性获取其内容并自动附加到TextBox。为了便于学习,这是一个简化的示例

LabeledTextBox.cs 公共类LabeledTextBox:TextBox { 静态标签文本框=> DefaultStyleKeyProperty.OverrideMetataTypeOfLabeledTextBox, 新的FrameworkPropertyMetadatatypeofLabeledTextBox; 公共静态只读DependencyProperty LabelProperty= DependencyProperty.RegisterLabel、typeofstring、typeofLabeledTextBox; 公共字符串标签 { get=>stringGetValueLabelProperty; set=>SetValueLabelProperty,值; } } Themes/Generic.xaml XAML中的ContentPresenter.ContentSource无效


我知道我可以在ControlTemplate中添加一个TextBox,但这意味着要么丢失继承的TextBox的所有属性,要么需要手动附加所有属性,这就破坏了对UserControl使用自定义控件的整个目的。

您需要使用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>
只需将目标绑定到TemplatedParent:

你的意思是Target={Binding ElementName=PART_ContentHost}?为什么是ScrollViewer?这仅仅是因为微软设计TextBoxBase的方式吗?假设我想基于LabeledTextBox创建第二个控件ButtonLabeledTextBox,以包含一个按钮。我还会使用ScrollViewer将LabeledTextBox放置在我的ButtonLabeledTextBox中吗?@dfoverdex Microsoft使用ScrollViewer支持文本框中的内容滚动。这取决于您的设计以及您想要的纽扣文本框外观和感觉。在这种情况下,您可以在标签顶部添加一个按钮。
<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>