如何更改WPF中TextBox的禁用背景颜色

我见过以下与我的问题有关的线程:

WPFcombobox:禁用时的背景颜色

以上处理更改ComboBox的内容模板。 我正在使用WPF,对样式和模板有些新颖,我想将禁用的TextBox的暗灰色背景颜色更改为其他颜色。 我们经常在我们的应用程序中使用TextBoxes ,我们发现默认的颜色设置难以阅读。

我已经制定了以下解决scheme尝试。 但当然,这是行不通的。 有人可以给我一个意见,为什么?

上传图片

不幸的是,对于TextBox控件来说,它看起来不像添加触发器那么简单,并且在触发条件为真时更改背景颜色。 您必须覆盖整个ControlTemplate才能实现此目的。 下面是你如何做到这一点的一个例子:

 <Window x:Class="StackOverflow.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <SolidColorBrush x:Key="DisabledForegroundBrush" Color="Red" /> <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="White" /> <Style TargetType="TextBox"> <Setter Property="Background" Value="White"/> <Setter Property="BorderBrush" Value="Black"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TextBox"> <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> <ScrollViewer Name="PART_ContentHost" Background="{TemplateBinding Background}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="False"> <Setter Value="{StaticResource DisabledBackgroundBrush}" Property="Background" /> <Setter Value="{StaticResource DisabledForegroundBrush}" Property="Foreground" /> <Setter TargetName="PART_ContentHost" Property="Background" Value="Blue"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Canvas> <TextBox Text="TextBox" IsEnabled="False"/> <TextBox Text="TextBox" IsEnabled="True" Canvas.Top="25"/> </Canvas> </Window> 

编辑:

为了回应你的问题,我尝试在上面添加ComboBox样式到我原来的答案,我能够没有错误地整合它。 我不确定,如果它performance得像你想的那样。 我只是复制粘贴你指定的链接。

 <Window x:Class="StackOverflow.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:StackOverflow" Title="MainWindow" Height="350" Width="525" x:Name="window"> <Window.Resources> <SolidColorBrush x:Key="DisabledForegroundBrush" Color="Red" /> <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="Blue" /> <LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#FFF" Offset="0.0"/> <GradientStop Color="#CCC" Offset="1.0"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="HorizontalNormalBrush" StartPoint="0,0" EndPoint="1,0"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#FFF" Offset="0.0"/> <GradientStop Color="#CCC" Offset="1.0"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="LightBrush" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#FFF" Offset="0.0"/> <GradientStop Color="#EEE" Offset="1.0"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="HorizontalLightBrush" StartPoint="0,0" EndPoint="1,0"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#FFF" Offset="0.0"/> <GradientStop Color="#EEE" Offset="1.0"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="DarkBrush" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#FFF" Offset="0.0"/> <GradientStop Color="#AAA" Offset="1.0"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="PressedBrush" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#BBB" Offset="0.0"/> <GradientStop Color="#EEE" Offset="0.1"/> <GradientStop Color="#EEE" Offset="0.9"/> <GradientStop Color="#FFF" Offset="1.0"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" /> <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" /> <!-- Border Brushes --> <LinearGradientBrush x:Key="NormalBorderBrush" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#CCC" Offset="0.0"/> <GradientStop Color="#444" Offset="1.0"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="HorizontalNormalBorderBrush" StartPoint="0,0" EndPoint="1,0"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#CCC" Offset="0.0"/> <GradientStop Color="#444" Offset="1.0"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="DefaultedBorderBrush" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#777" Offset="0.0"/> <GradientStop Color="#000" Offset="1.0"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="PressedBorderBrush" StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#444" Offset="0.0"/> <GradientStop Color="#888" Offset="1.0"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> <SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA" /> <SolidColorBrush x:Key="SolidBorderBrush" Color="#888" /> <SolidColorBrush x:Key="LightBorderBrush" Color="#AAA" /> <!-- Miscellaneous Brushes --> <SolidColorBrush x:Key="GlyphBrush" Color="#444" /> <SolidColorBrush x:Key="LightColorBrush" Color="#DDD" /> <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition Width="20" /> </Grid.ColumnDefinitions> <Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="2" Background="{StaticResource NormalBrush}" BorderBrush="{StaticResource NormalBorderBrush}" BorderThickness="1" /> <Border Grid.Column="0" CornerRadius="2,0,0,2" Margin="1" Background="{StaticResource WindowBackgroundBrush}" BorderBrush="{StaticResource NormalBorderBrush}" BorderThickness="0,0,1,0" /> <Path x:Name="Arrow" Grid.Column="1" Fill="{StaticResource GlyphBrush}" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="ToggleButton.IsMouseOver" Value="true"> <Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" /> </Trigger> <Trigger Property="ToggleButton.IsChecked" Value="true"> <Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" /> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" /> <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" /> <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/> <Setter TargetName="Arrow" Property="Fill" Value="{StaticResource DisabledForegroundBrush}" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox"> <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" /> </ControlTemplate> <Style x:Key="{x:Type ComboBox}" TargetType="ComboBox"> <Setter Property="SnapsToDevicePixels" Value="true"/> <Setter Property="OverridesDefaultStyle" Value="true"/> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> <Setter Property="ScrollViewer.CanContentScroll" Value="true"/> <Setter Property="MinWidth" Value="120"/> <Setter Property="MinHeight" Value="20"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ComboBox"> <Grid> <ToggleButton Name="ToggleButton" Template="{StaticResource ComboBoxToggleButton}" Grid.Column="2" Focusable="false" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"> </ToggleButton> <ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3,3,23,3" VerticalAlignment="Center" HorizontalAlignment="Left" /> <TextBox x:Name="PART_EditableTextBox" Style="{x:Null}" Template="{StaticResource ComboBoxTextBox}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,3,23,3" Focusable="True" Background="Transparent" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}"/> <Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide"> <Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}"> <Border x:Name="DropDownBorder" Background="{StaticResource WindowBackgroundBrush}" BorderThickness="1" BorderBrush="{StaticResource SolidBorderBrush}"/> <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True"> <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" /> </ScrollViewer> </Grid> </Popup> </Grid> <ControlTemplate.Triggers> <Trigger Property="HasItems" Value="false"> <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/> </Trigger> <Trigger Property="IsGrouping" Value="true"> <Setter Property="ScrollViewer.CanContentScroll" Value="false"/> </Trigger> <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true"> <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/> <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/> </Trigger> <Trigger Property="IsEditable" Value="true"> <Setter Property="IsTabStop" Value="false"/> <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/> <Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> </Style.Triggers> </Style> <Style TargetType="TextBox"> <Setter Property="Background" Value="White"/> <Setter Property="BorderBrush" Value="Black"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TextBox"> <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> <ScrollViewer Name="PART_ContentHost" Background="{TemplateBinding Background}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="False"> <Setter Value="{StaticResource DisabledBackgroundBrush}" Property="Background" /> <Setter Value="{StaticResource DisabledForegroundBrush}" Property="Foreground" /> <Setter TargetName="PART_ContentHost" Property="Background" Value="{StaticResource DisabledBackgroundBrush}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <StackPanel> <TextBox IsEnabled="False">TextBox</TextBox> <ComboBox IsEnabled="False"/> </StackPanel> </Window> 

你可以使用下面的代码片段:

而不是检查IsEnable属性,使用TextBox控件的IsReadonly属性。

 <Style TargetType="{x:Type TextBox}"> <Setter Property="Background" Value="LightSkyBlue" /> <Style.Triggers> <Trigger Property="IsReadOnly" Value="True"> <Setter Property="Background" Value="Red" /> </Trigger> </Style.Triggers> </Style> 

如果您需要将其应用于所有文本框控件,请使用上面的代码。 对于特定的文本框,只需设置键并将样式应用于该文本框。

对于这种情况,我喜欢设置Focusable=false ,并将背景颜色设置为我所需的值(在数据绑定触发器中)。 这可能是一个小黑客,但重写整个TextBox的控制模板也是如此。 Focusable的另一个select是IsReadyOnly ,但是这对于许多控件来说都不起作用。 它确实确保了脱字符号消失。

尽量避免重新定义控制模板。 它们往往会增加很多代码开销,并且随着时间的推移会变得很难维护。

我会在Loaded事件中使用下面的代码:

 ClassicBorderDecorator o = VisualTreeHelper.GetChild(this.textBox1, 0) as ClassicBorderDecorator; if (o != null) { o.Background = new SolidColorBrush(Colors.Transparent); } 

您从不使用您定义的ControlTemplate。 此外,你想要一个样式,而不是(必然)一个ControlTemplate。

我想你想要的东西如下所示:

 <Canvas.Resources> <SolidColorBrush x:Key="DisabledForegroundBrush" Color="Red" /> <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="White" /> <Style TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}" /> <Setter Property="Background" Value="{StaticResource DisabledBackgroundBrush}" /> </Trigger> </Style.Triggers> </Style> </Canvas.Resources> 

如果您查看文本框的模板,您会注意到该模板具有IsEnabled属性False的触发器,并将其边框元素“Bd”背景颜色设置为SystemColors.ControlBrushKey。

如果你用一种风格重写这种颜色,它将实现你想要做的事情。

 <Style TargetType="{x:Type TextBox}"> <Style.Resources> <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{StaticResource MyNewTextBoxBackgroundColor}" /> </Style.Resources> </Style> 
 By adding <Window.Resources> after <Window> and before <Grid> will make your text box behave like normal winforms textbox. <Window x:Class="..." Height="330" Width="600" Loaded="Window_Loaded" WindowStartupLocation="CenterOwner"> <Window.Resources> <Style TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="IsReadOnly" Value="True"> <Setter Property="Background" Value="LightGray" /> </Trigger> <Trigger Property="IsReadOnly" Value="False"> <Setter Property="Background" Value="White" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Grid> 

取自以下网页的代码:

wpf:select文本框中的文本IsReadOnly = true?

并修改风格以匹配winforms。 (它们的外观已启用= false,而不是readonly = true)

当然,您的文本框必须具有IsReadOnly =“True”属性集。