WPF重写TextBox模板后,如何通过触发器控制内部ScrollViewer背景
解决WPF TextBox验证时背景不生效的问题
你遇到的问题根源是:Style触发器修改的是TextBox自身的Background属性,但模板内的ScrollViewer和Border都硬编码了背景值,没有绑定到TextBox的属性,所以外部Setter无法覆盖模板内部元素的样式。另外,Style级别的触发器无法直接引用模板内的命名元素(比如PART_ContentHost),需要把触发器移到ControlTemplate内部来操作。
修正方案
- 将模板内元素的
Background改为绑定到TextBox的对应属性,让Style的设置能传递进去 - 在
ControlTemplate.Triggers中添加验证错误触发器,直接修改模板内元素的样式
修改后的完整代码
<Style TargetType="TextBox"> <Setter Property="FontSize" Value="20"/> <!-- 设置默认背景,替代模板内的硬编码 --> <Setter Property="Background" Value="Gray"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TextBox"> <StackPanel> <Border CornerRadius="2" Padding="2" Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1"> <!-- 绑定TextBox的Background,去掉硬编码的Gray --> <ScrollViewer Margin="0" x:Name="PART_ContentHost"/> </Border> <ItemsControl FontSize="10" ItemsSource="{TemplateBinding Validation.Errors}"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Foreground="Red" Text="{Binding Path=ErrorContent}"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> <!-- 模板内部触发器,直接操作模板内元素 --> <ControlTemplate.Triggers> <Trigger Property="Validation.HasError" Value="True"> <!-- 修改ScrollViewer的背景为红色,也可以选择修改Border --> <Setter TargetName="PART_ContentHost" Property="Background" Value="Red"/> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
关键修改说明
- 把模板内
Border的Background改为{TemplateBinding Background},ScrollViewer去掉硬编码的Background,让TextBox的Background属性设置能传递到模板元素 - 将验证错误触发器从
Style.Triggers移到ControlTemplate.Triggers,通过TargetName直接引用模板内的PART_ContentHost来修改背景 - 在Style的Setter中设置默认背景为Gray,替代原来模板内的硬编码值,保持默认外观一致
内容的提问来源于stack exchange,提问作者aldo
相关产品推荐
相关产品推荐

