none
C#(WPF)のtextboxの背景色と、Disabledの時やReadOnlyの時の背景色の変更について RRS feed

  • 質問

  • いつもお世話になっております。

    C#(WPF)のtextboxの背景色と、Disabledの時やReadOnlyの時の背景色の変更についてアドバイスお願い致します。

    環境は.Net Framework 4.6 Visual Studio 2017 を使用しております。

    textboxの背景色の変更は、Backgroundにて変更が可能ですが、非活性状態(Disabled)の時やReadOnly時の背景色の変更がどうもうまくいきません。

    マイクロソフトのサイト(https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/controls/textbox-styles-and-templates)にあるControlTemplateをコピーしてstyleにセットしてみました。

    <Style TargetType="{x:Type TextBox}">
      <Setter Property="SnapsToDevicePixels"
              Value="True" />
      <Setter Property="OverridesDefaultStyle"
              Value="True" />
      <Setter Property="KeyboardNavigation.TabNavigation"
              Value="None" />
      <Setter Property="FocusVisualStyle"
              Value="{x:Null}" />
      <Setter Property="MinWidth"
              Value="120" />
      <Setter Property="MinHeight"
              Value="20" />
      <Setter Property="AllowDrop"
              Value="true" />
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type TextBoxBase}">
            <Border Name="Border"
                    CornerRadius="2"
                    Padding="2"
                    BorderThickness="1">
              <Border.Background>
                <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
              </Border.Background>
              <Border.BorderBrush>
                <SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
              </Border.BorderBrush>
              <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                  <VisualState x:Name="Normal" />
                  <VisualState x:Name="Disabled">
                    <Storyboard>
                      <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                    Storyboard.TargetProperty="(Panel.Background).
                        (SolidColorBrush.Color)">
                        <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource DisabledControlLightColor}" />
                      </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                  </VisualState>
                  <VisualState x:Name="ReadOnly">
                    <Storyboard>
                      <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                    Storyboard.TargetProperty="(Panel.Background).
                        (SolidColorBrush.Color)">
                        <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource DisabledControlDarkColor}" />
                      </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                  </VisualState>
                  <VisualState x:Name="MouseOver" />
                </VisualStateGroup>
              </VisualStateManager.VisualStateGroups>
              <ScrollViewer Margin="0"
                            x:Name="PART_ContentHost" />
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

    DisabledControlLightColor あたりを変えればよいかと思い試してみましたが、ダイアログの背景色と同じになってしまい思うような動作になりませんでした。

    textboxの非活性状態(Disabled)の時やReadOnly時の背景色の変更方法をご存じの方がいらっしゃいましたらご教授お願い致します。

    よろしくお願いいたします。

    2020年7月3日 13:06

回答

  • DisabledControlLightColorの箇所をどのように変更したのでしょうか?

    <StackPanel>
        <StackPanel.Resources>
            <Color x:Key="testColor" >#FFFF00FF</Color>
    
            <Style TargetType="{x:Type TextBox}" x:Key="testStyle">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TextBoxBase}">
                            <Border Name="Border"
                            CornerRadius="2"
                            Padding="2"
                            BorderThickness="1">
                                <Border.Background>
                                    <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
                                </Border.Background>
                                <Border.BorderBrush>
                                    <SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
                                </Border.BorderBrush>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal" />
                                        <VisualState x:Name="Disabled">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                            Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                                    <EasingColorKeyFrame KeyTime="0" Value="Red" />
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="ReadOnly">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                            Storyboard.TargetProperty="(Panel.Background). (SolidColorBrush.Color)">
                                                    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource testColor}"/>
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="MouseOver" />
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <ScrollViewer Margin="0" x:Name="PART_ContentHost" />
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </StackPanel.Resources>
    
        <TextBox Text="スタイル未適用" Style="{x:Null}" 
                IsReadOnly="{Binding ElementName=chkIsReadOnly,Path=IsChecked,Mode=OneWay}" 
                IsEnabled="{Binding ElementName=chkIsEnabled,Path=IsChecked,Mode=OneWay}" />
    
        <TextBox Text="スタイル適用" Style="{StaticResource testStyle}"
                IsReadOnly="{Binding ElementName=chkIsReadOnly,Path=IsChecked,Mode=OneWay}" 
                IsEnabled="{Binding ElementName=chkIsEnabled,Path=IsChecked,Mode=OneWay}" />
    
        <CheckBox Content="IsReadOnly" x:Name="chkIsReadOnly"/>
        <CheckBox Content="IsEnabled" x:Name="chkIsEnabled" IsChecked="True"/>
    </StackPanel>


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク coco2014 2020年7月6日 2:41
    2020年7月3日 14:19

すべての返信

  • DisabledControlLightColorの箇所をどのように変更したのでしょうか?

    <StackPanel>
        <StackPanel.Resources>
            <Color x:Key="testColor" >#FFFF00FF</Color>
    
            <Style TargetType="{x:Type TextBox}" x:Key="testStyle">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TextBoxBase}">
                            <Border Name="Border"
                            CornerRadius="2"
                            Padding="2"
                            BorderThickness="1">
                                <Border.Background>
                                    <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
                                </Border.Background>
                                <Border.BorderBrush>
                                    <SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
                                </Border.BorderBrush>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal" />
                                        <VisualState x:Name="Disabled">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                            Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                                    <EasingColorKeyFrame KeyTime="0" Value="Red" />
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="ReadOnly">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                            Storyboard.TargetProperty="(Panel.Background). (SolidColorBrush.Color)">
                                                    <EasingColorKeyFrame KeyTime="0" Value="{StaticResource testColor}"/>
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="MouseOver" />
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <ScrollViewer Margin="0" x:Name="PART_ContentHost" />
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </StackPanel.Resources>
    
        <TextBox Text="スタイル未適用" Style="{x:Null}" 
                IsReadOnly="{Binding ElementName=chkIsReadOnly,Path=IsChecked,Mode=OneWay}" 
                IsEnabled="{Binding ElementName=chkIsEnabled,Path=IsChecked,Mode=OneWay}" />
    
        <TextBox Text="スタイル適用" Style="{StaticResource testStyle}"
                IsReadOnly="{Binding ElementName=chkIsReadOnly,Path=IsChecked,Mode=OneWay}" 
                IsEnabled="{Binding ElementName=chkIsEnabled,Path=IsChecked,Mode=OneWay}" />
    
        <CheckBox Content="IsReadOnly" x:Name="chkIsReadOnly"/>
        <CheckBox Content="IsEnabled" x:Name="chkIsEnabled" IsChecked="True"/>
    </StackPanel>


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク coco2014 2020年7月6日 2:41
    2020年7月3日 14:19
  • gekkaさん

    いつもありがとうございます。

    大変助かります。

    指定した色には変更できました。ただ、デフォルトの背景色(IsEnabledがtrueの時)が、ダイアログの背景色と同じになってしまい、思うように動かないのです。

    gekkaさんのコードでいう、<stackPanel> を <stackPanel Background="Black"> とすると再現すると思います。

    私のコードでは<stackPanel>ではなく、Gridでやってましたが、同じでした。 

    <Grid Background="Black">

    <Text="スタイル適用" Background="Yellow" Style="{StaticResource testStyle}" IsReadOnly="{Binding ElementName=chkIsReadOnly,Path=IsChecked,Mode=OneWay}" IsEnabled="{Binding ElementName=chkIsEnabled,Path=IsChecked,Mode=OneWay}" />

    いつも本当に助かります。

    よろしくお願いいたします。

    2020年7月3日 15:27
  • 提示されているテンプレートだと通常時のバックグランドは

    <Border.Background>
        <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
    </Border.Background>

    になります。
    ここでDynamicResourceとなっているので、どこかのリソースでControlLightColorというキーを持ったリソースが定義されている場合はその値を使用して、定義されていなければ値が設定されないという挙動になります。
    つまり、リソースが設定されていないと背景色が透明になってしまうという事です。

    ですから、

    <StackPanel.Resources>
        <Color x:Key="testColor" >#FFFF00FF</Color>
        <Color x:Key="ControlLightColor" >#FFFFFF00</Color>

    のようにキーがControlLightColorのリソースを定義してやるか、

    <ControlTemplate TargetType="{x:Type TextBoxBase}">
        <Border Name="Border" CornerRadius="2" Padding="2" BorderThickness="1" 
                Background="LemonChiffon">

    のように直接バックグランドを指定してやるか、

    <ControlTemplate TargetType="{x:Type TextBoxBase}">
        <Border Name="Border" CornerRadius="2" Padding="2" BorderThickness="1" 
                Background="{TemplateBinding Background}">
    のようにしてからTextBoxのBackgroundプロパティを参照するようにする方法があります。
    <TextBox Text="スタイル適用" Style="{StaticResource testStyle}"
                Background="LightYellow"



    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2020年7月3日 16:52
  • gekkaさん

    詳細な説明ありがとうございます。

    まだまだWPF勉強不足で申し訳ございません。

    そういうことだったんですね。背景色になってしまう理由、理解できました。

    gekkaさんのおかげで、WPFも少しずつ理解できてきました。

    もっと勉強しなきゃですね。

    ありがとうございました。


    2020年7月6日 2:41