WPF 如何从TextBox向ResourceDictionary内模板TextBlock的Text属性传值
问题描述
如何从TextBox控件向ResourceDictionary内自定义TextBox样式模板中的TextBlock控件的Text属性传值?
目前已通过Tag属性向模板内的Path传递图标数据,绑定表达式为:Data="{Binding Tag, RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}"
现有代码
Page.xaml 中的TextBox定义
<TextBox x:Name="SearchTextBox" VerticalAlignment="Center" VerticalContentAlignment="Center" Tag="{StaticResource SearchIcon}"/>
ResourceDictionary.xaml 中的TextBox样式模板
<Style TargetType="{x:Type TextBox}"> ... <TextBlock x:Name="SearchTextBlock" Grid.Column="1" Foreground="{TemplateBinding Foreground}" Text="??? 待绑定值" VerticalAlignment="Center"/> <ScrollViewer Grid.Column="1" VerticalContentAlignment="Center" x:Name="PART_ContentHost" /> ... </Style>
解决方案
你定义的TextBlock属于TextBox的ControlTemplate内部元素,绑定模板所属的TextBox实例的属性,直接用RelativeSource TemplatedParent即可,性能比向上查找祖先的写法更好,也不会出现嵌套控件找错绑定源的问题。
根据你要传的数据源不同,对应绑定写法如下:
- 若要绑定TextBox本身的
Tag属性值:Text="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}" - 若要绑定TextBox本身的输入内容
Text属性:Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" - 若该TextBlock是搜索占位提示(TextBox无输入时显示提示,有输入时隐藏),不需要绑定外部动态值,直接给TextBlock写死提示文本,再加触发器关联TextBox的Text状态即可:
<TextBlock x:Name="SearchTextBlock" Grid.Column="1" Foreground="{TemplateBinding Foreground}" Text="请输入搜索关键词" VerticalAlignment="Center"> <TextBlock.Style> <Style TargetType="TextBlock"> <!-- 默认隐藏占位提示 --> <Setter Property="Visibility" Value="Collapsed"/> <Style.Triggers> <!-- 输入框为空字符串时显示提示 --> <DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" Value=""> <Setter Property="Visibility" Value="Visible"/> </DataTrigger> <!-- 输入框初始为null时显示提示 --> <DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" Value="{x:Null}"> <Setter Property="Visibility" Value="Visible"/> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock>
如果需要给不同的TextBox实例传不同的提示文本,不用硬编码在模板里,可以给TextBox添加自定义依赖属性(如PlaceholderText),之后在模板里绑定该自定义属性即可。
你之前用的
RelativeSource AncestorType={x:Type TextBox}写法也能生效,但如果模板内嵌套了其他TextBox控件,会优先找到上层的其他TextBox,TemplatedParent只会指向直接应用当前模板的TextBox实例,匹配逻辑更准确。
内容的提问来源于stack exchange,提问作者nekigh
相关产品推荐
相关产品推荐

