2010-09-20 72 views
28

我看到下面的線程這是關係到我的問題:如何改變文本框的禁用背景色WPF

WPF ComboBox: background color when disabled

以上涉及改變內容模板的ComboBox。我正在與WPF合作,對樣式和模板有點新,我想將其它顏色的灰色背景顏色改爲其他顏色的TextBox。經常在我們的應用程序中使用TextBoxes,我們發現默認顏色設置難以閱讀。

我制定了以下解決方案嘗試。但當然,這是行不通的。有人可以給我一個意見,爲什麼?

Upload Image

回答

29

不幸的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>  

編輯:

在回答你的問題,我嘗試添加組合框風格我上面原來的答覆,我是能夠整合它沒有錯誤。我不確定它是否像你想要的那樣行事。我只是複製粘貼了你指定的鏈接。

<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

上面的例子在我的測試中有效。謝謝!我想知道我是否可以添加一個跟進。我需要類似ComboBox的功能,這似乎是交給我的銀盤上與此鏈接:http://msdn.microsoft.com/en-us/library/ms752094%28v=VS.85%29。 aspx然而,我很難將這兩者結合起來。如果我將TextBox上面的樣式和引用鏈接中的內容模板放在一個「Window.Resources」文件中,它會產生語法錯誤。你能給我這方面的指導嗎? – 2010-09-20 19:38:53

+0

你有什麼錯誤?好吧,我會嘗試將ComboBox的ControlTemplate集成到上面的示例中,看看我能否使其工作。我會就此回覆你。 – ASanch 2010-09-20 20:10:05

+0

查看我上面編輯的XAML。 – ASanch 2010-09-20 20:16:24

1

你從來不會使用您定義的控件模板。另外,你需要一個Style,而不是(必須)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> 
+0

Wonko the Sane(這是一個很棒的屏幕名稱),...我無法得到上面的例子工作(它似乎沒有修改任何東西)。然而,它很優雅,比下面的迴應短得多,所以它會很棒......但是沒有運氣。感謝您的答覆。 – 2010-09-20 19:37:56

+0

@ user452763(不完全像一個屏幕名稱令人難忘) - 是的,karmicpuppet是正確的。我相信它與TextBox控件由其他控件組成的方式有關。 – 2010-09-20 20:00:41

7

對於這種情況,我喜歡設置Focusable=false和背景顏色設置到我的所需值(在數據綁定觸發)。這可能有點冒險,但重寫整個TextBox的控制模板也是如此。 Focusable的替代方法是IsReadyOnly,但這不適用於多個控件。但它確實確保了脫字符號消失。

2

儘量避免在可以的地方重新定義控件模板。它們往往會增加很多代碼開銷,並且隨着時間的推移會變得很難維護。

我會用下面的代碼加載的事件:

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

您可以使用下面的代碼片段:

不是檢查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> 

如果您需要將其應用於所有文本框控件,請使用上面的代碼。 對於特定的文本框,只需設置該鍵並將該樣式應用於該文本框。

+0

在我的情況下,這是行不通的,因爲控件是禁用面板中的一組控件的一部分。當面板被禁用時,文本字段被隱式禁用,一旦它被禁用,它將恢復爲例如純白色背景,而不是我設置的半透明背景。 – Triynko 2014-02-13 19:16:56

1

如果您查看文本框的模板,您會注意到該模板具有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> 
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> 

代碼:

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

和風格修改,以符合的WinForms。 (它們的外觀已啓用= false,而不是隻讀= true)

當然,您的文本框必須具有IsReadOnly =「True」屬性集。