如何让WinUI3 TextBox前景色在控件状态切换时不被覆盖
解决WinUI3 TextBox错误状态文本颜色被控件状态覆盖的问题
不用重写整个TextBox模板的话,有两种简洁的实现方式:
方式一:MultiBinding + 资源覆盖
这种方式通过绑定动态切换默认主题色和错误红色,同时覆盖控件状态对应的资源,确保所有状态下颜色一致:
- 先实现一个多值转换器,根据错误状态返回对应颜色:
public class ErrorForegroundConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, string language) { if (values.Length != 2 || !(values[0] is bool isError) || !(values[1] is Brush defaultBrush)) return defaultBrush; return isError ? new SolidColorBrush(Colors.Red) : defaultBrush; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, string language) { throw new NotImplementedException(); } }
- 在XAML中配置TextBox,用MultiBinding绑定Foreground,同时覆盖PointerOver、Focused状态的资源:
<Page.Resources> <local:ErrorForegroundConverter x:Key="ErrorForegroundConverter" /> </Page.Resources> <TextBox> <TextBox.Foreground> <MultiBinding Converter="{StaticResource ErrorForegroundConverter}"> <Binding Path="IsError" Mode="OneWay" /> <Binding Source="{ThemeResource TextControlForeground}" Mode="OneWay" /> </MultiBinding> </TextBox.Foreground> <TextBox.Resources> <!-- 让状态变化时复用Foreground的颜色 --> <SolidColorBrush x:Key="TextControlForegroundPointerOver" Color="{Binding Path=Foreground.Color, RelativeSource={RelativeSource Self}, Mode=OneWay}" /> <SolidColorBrush x:Key="TextControlForegroundFocused" Color="{Binding Path=Foreground.Color, RelativeSource={RelativeSource Self}, Mode=OneWay}" /> </TextBox.Resources> </TextBox>
方式二:自定义VisualState切换
通过添加自定义视觉状态,在错误状态下直接覆盖对应资源和Foreground:
<TextBox x:Name="ErrorTextBox"> <VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState x:Name="Normal"/> <VisualState x:Name="Error"> <VisualState.Setters> <Setter Target="ErrorTextBox.Foreground" Value="Red"/> <Setter Target="ErrorTextBox.Resources[TextControlForegroundPointerOver]" Value="Red"/> <Setter Target="ErrorTextBox.Resources[TextControlForegroundFocused]" Value="Red"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </TextBox>
然后在代码中根据错误状态切换视觉状态:
// 假设IsError是ViewModel中的布尔属性,用于标记是否错误 VisualStateManager.GoToState(ErrorTextBox, IsError ? "Error" : "Normal", true);
关于你之前的空引用错误
你之前用x:Bind报错是因为:TextBox的Resources字典默认不继承页面的DataContext,编译时x:Bind找不到NameTextColour属性导致空引用。换成Binding并指定RelativeSource(比如RelativeSource={RelativeSource AncestorType=Page})就能解决这个问题。
内容的提问来源于stack exchange,提问作者Siyh
相关产品推荐
相关产品推荐

