在wpf中自定义样式时,文本框的文本始终为空

brqmpdu1  于 2022-12-05  发布在  其他
关注(0)|答案(3)|浏览(205)

嘿,我正在使用XAML代码为WPF应用程序中的文本框设计一个新样式。文本框是文本框和文本块的组合,我使用文本块在文本为空时显示文本框的名称,并在文本填充时消失。但有一个问题,当我运行应用程序,并填写一些东西的文本框,它似乎s工作正常,但在后端,当我想访问文本框文本,它是空的,即使它是填充!!!我做了什么错误的基础或我错过了什么要做的。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type TextBox}"
           x:Key="TextBoxTheme">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Border CornerRadius="10"
                            Background="#353340"
                            Width="200"
                            Height="40">
                        <Grid>
                            <Rectangle StrokeThickness="1"/>
                            <TextBox Margin="1" 
                                     Text="{TemplateBinding Property=Text}"
                                     BorderThickness="0"
                                     Background="Transparent"
                                     VerticalAlignment="Center"
                                     Padding="5"
                                     Foreground="#CFCFCF"
                                     x:Name="textBox"/>
                            <TextBlock IsHitTestVisible="False"
                                       Text="{TemplateBinding Name}"
                                       VerticalAlignment="Center"
                                       HorizontalAlignment="Left"
                                       Margin="10, 0, 0, 0"
                                       FontSize="11"
                                       Foreground="DarkGray">
                                <TextBlock.Style>
                                    <Style TargetType="{x:Type TextBlock}">
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Text, ElementName=textBox}" Value="">
                                                <Setter Property="Visibility" Value="Visible"/>
                                            </DataTrigger>
                                        </Style.Triggers>
                                        <Setter Property="Visibility" Value="Hidden"/>
                                    </Style>
                                </TextBlock.Style>
                            </TextBlock>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

    </Style>
</ResourceDictionary>
2nbm6dog

2nbm6dog1#

您没有为TextBox提供显示其内容的区域,而是将它与另一个TextBox重叠在顶部。
若要显示其内容,TextBox会在Template中寻找ScrollViewer x:Name="PART_ContentHost"
请尝试使用以下模板:

<Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                            <Grid>
                                <TextBlock x:Name="PART_TextBlock" Text="{TemplateBinding Name}" Visibility="Collapsed"/>
                                <ScrollViewer x:Name="PART_ContentHost"
                                          Focusable="false"
                                          HorizontalScrollBarVisibility="Hidden"
                                          VerticalScrollBarVisibility="Hidden"/>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="Text"
                                         Value="{x:Static sys:String.Empty}">
                                <Setter TargetName="PART_TextBlock" Property="Visibility" Value="Visible"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
k4emjkb1

k4emjkb12#

在YouTube视频评论中找到了这个问题代码的来源。在模板xaml文件中执行以下操作:
替换此:Text="{TemplateBinding Text}"
使用此:Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text, UpdateSourceTrigger=PropertyChanged}"
在此更改之后,我能够从TextChanged事件中捕获文本。

whlutmcx

whlutmcx3#

如果选中the documentation for TemplateBinding,您将看到它只是一个 * 单向 * RelativeSource绑定到模板化父对象的语法糖,因此您所需要做的就是更改TextBox绑定,使其成为双向绑定:

Text="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"

另外,我不同意上面关于这不是一个好主意的评论,WPF模板化系统的整个目的之一是使模板化现有控件成为可能,例如,用于库的重新分发等。也就是说,我不认为Name是用于提示文本的最佳属性,一个更好的解决方案是使用attached property .对于快速解决方案,还有Tag属性,你可以随意使用它。

相关问题