2010-09-20 2 views
28

Ich habe die folgenden Threads gesehen, die auf meine Frage zu ändern, verwandt ist:Wie deaktiviert Hintergrundfarbe von TextBox in WPF

WPF ComboBox: background color when disabled

Die oben genannten Angebote den Inhalt Vorlage für einen ComboBox mit zu verändern. Ich arbeite mit WPF, bin etwas neu bei Styles und Templates und möchte die graue Hintergrundfarbe eines deaktivierten TextBox in eine andere Farbe ändern. Wir verwenden TextBoxes häufig in unserer Anwendung und wir finden die Standardfarbeneinstellungen schwierig zu lesen.

Ich habe den folgenden Lösungsversuch erstellt. Aber natürlich funktioniert es nicht. Kann mir jemand eine Meinung dazu geben, warum?

Upload Image

Antwort

29

Leider für die TextBox-Steuerelement, scheint es, wie es ist nicht so einfach wie nur ein Trigger Hinzufügen und Ändern der Hintergrundfarbe, wenn die Triggerbedingung erfüllt ist. Sie müssen das gesamte ControlTemplate überschreiben, um dies zu erreichen. Unten ist ein Beispiel dafür, wie Sie dies tun könnten:

<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>  

EDIT:

Als Antwort auf Ihre Frage habe ich versucht, über den ComboBox Stil zu meiner ursprünglichen Antwort hinzufügen und ich war in der Lage, es zu integrieren ohne Fehler. Ich bin mir aber nicht sicher, ob es sich so verhält, wie du es wolltest. Ich kopiere einfach, was in dem von Ihnen angegebenen Link enthalten ist.

<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> 
+0

Das obige Beispiel hat in meinen Tests funktioniert. Vielen Dank! Ich fragte mich, ob ich eine Nachfolge hinzufügen könnte. Ich brauche ähnliche Funktionalität für die ComboBox, und das scheint mir auf einem Silbertablett mit diesem Link überreicht zu werden: http://msdn.microsoft.com/en-us/library/ms752094%28v=VS.85%29. Aspx Allerdings habe ich Schwierigkeiten, die beiden zu kombinieren. Wenn ich sowohl den obigen Style für die TextBox als auch die Inhaltsvorlage aus dem Verweis in eine "Window.Resources" -Datei platziere, entstehen Syntaxfehler. Kannst du mir eine Anleitung geben? –

+0

Welche Fehler bekommen Sie? Nun, ich werde versuchen, das ControlTemplate für die ComboBox in mein Beispiel oben zu integrieren und zu sehen, ob ich es zum Laufen bringen kann. Ich melde mich zu diesem Thema. – ASanch

+0

Überprüfen Sie den XAML in meinem EDIT oben. – ASanch

1

Sie nie die Control verwenden Sie definiert. Außerdem möchten Sie einen Style, nicht (unbedingt) ein ControlTemplate.

Ich glaube, Sie so etwas wie die folgenden wollen:

<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> 
+0

Wonko der Sane (das ist ein großartiger Bildschirmname), ... Ich konnte das obige Beispiel nicht funktionieren (es schien nichts zu modifizieren). Es ist jedoch elegant und viel kürzer als die Antwort unten, also wäre es großartig ... aber kein Glück. Danke für Ihre Antwort. –

+0

@ user452763 (nicht ganz so ein denkwürdiger Bildschirmname) - ja, karmicpuppet ist richtig. Ich glaube, dass es damit zu tun hat, wie das TextBox-Steuerelement aus anderen Steuerelementen besteht. –

7

Für diese Situation Ich mag Focusable=false setzen und die Hintergrundfarbe zu meinem gewünschten Wert (in einem datengebundenen Trigger) gesetzt. Dies ist vielleicht ein wenig hacky, aber so ist das Steuerelement Vorlage für die gesamte TextBox neu zu schreiben. Eine Alternative zu Focusable ist IsReadyOnly, aber das funktioniert nicht für so viele Steuerungen. Es stellt jedoch sicher, dass der Caret verschwindet.

2

Versuchen Sie zu vermeiden, Steuerelementvorlagen neu zu definieren, wo Sie können. Sie neigen dazu, viel Code-Overhead hinzuzufügen und können im Laufe der Zeit schwierig zu pflegen sein.

würde ich den folgenden Code in das Loaded-Ereignis verwenden:

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

Sie das folgende Snippet verwenden können:

Statt Kontrolle für IsEnable Sach IsReadOnly-Eigenschaft von TextBox-Steuerelement verwenden.

<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> 

Wenn Sie es für alle Textfeldsteuerelemente anwenden müssen, verwenden Sie den obigen Code. Legen Sie für ein bestimmtes Textfeld einfach den Schlüssel fest und wenden Sie den Stil auf dieses Textfeld an.

+0

In meinem Fall wird das nicht funktionieren, weil das Steuerelement Teil einer Gruppe von Steuerelementen in einem Panel ist, das deaktiviert ist. Wenn das Panel deaktiviert ist, wird das Textfeld implizit deaktiviert, und sobald es deaktiviert ist, wird es zum Beispiel auf einen durchgehend weißen Hintergrund anstelle des von mir eingestellten durchscheinenden Hintergrunds zurückgesetzt. – Triynko

1

Wenn Sie sich die Vorlage des Textfelds ansehen, werden Sie feststellen, dass die Vorlage einen Trigger für die IsEnabled-Eigenschaft False hat und die Hintergrundfarbe des Rahmenelements "Bd" auf SystemColors.ControlBrushKey setzt.

Wenn Sie diese Farbe in einem Stil überschreiben, wird es erreichen, was Sie tun möchten.

<Style TargetType="{x:Type TextBox}"> 
    <Style.Resources> 
    <SolidColorBrush 
     x:Key="{x:Static SystemColors.ControlBrushKey}" 
     Color="{StaticResource MyNewTextBoxBackgroundColor}" /> 
    </Style.Resources> 
</Style> 
0
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> 

-Code von folgenden Webseite entnommen:

wpf: Selecting the Text in TextBox with IsReadOnly = true?

und Stil geändert winforms anzupassen. (Ihr Aussehen ist aktiviert = false, nicht readonly = true)

Und natürlich muss Ihr Textfeld IsReadOnly = "True" -Attribut gesetzt haben.