none
フォーカスを合わせた際のTextBoxの色について RRS feed

  • 質問

  • 例えば、背景色を青、文字色を赤に設定していても、
    フォーカスを合わせると、必ず背景色白、文字色黒になってしまいます。

    上記の現象を防ぐために、GotFocus()で色変更を行い、
    LostFocus()で元の色に戻す処理を入れたのですが、
    これもうまくいきませんでした。

    フォーカスが当たっているTextBoxのForegroundとBackgroundの色を
    変える方法をご存知の方、ご教授願えないでしょうか?
    (もしくはTextBoxはフォーカス中の色の変更はできないのでしょうか?)

    環境
    Windows10
    Visual Stadio2015
    C++/CX
    2017年11月27日 2:33

回答

  • 質問するときは開発環境およびターゲット環境のWindows 10バージョンやエディションなども詳しく書くようにしてください。

    UWPでコントロールの外観をカスタマイズする場合、ControlTemplateを使いますが、その前にまずUWP (XAML) における既定の外観定義の仕組みを説明します。

    開発環境が64bit版Windows 10である場合、既定のコントロールの外観は、以下のXAMLファイルにて定義されています。

    %ProgramFiles(x86)%/Windows Kits/10/DesignTime/CommonConfiguration/Neutral/UAP/10.0.*.*/Generic/generic.xaml

    10.0.*.*の数値は開発環境にインストールされているWindows 10 SDKのバージョンに対応します。generic.xamlの中身は、SDKのバージョンによって多少異なります。プロジェクト作成時に選択したターゲットバージョンに応じて使用されるSDKも変わります。

    一例として、TextBox styles and templates - Windows app developmentには、Version 1511 (10.0.10586.0) のgeneric.xamlにおけるTextBoxの既定Styleが記載されています。

    既定のControlTemplateの記述において、フォーカスされたときのVisualStateが記述されています。ここでTextBoxを構成する内部の部品の外観を変更していますが、Windows.Control.ForegroundやBackgroundプロパティは使われず、テーマリソースで定義済みのシステムカラーブラシが使われています。

    <VisualState x:Name="Focused">
      <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter"
                                       Storyboard.TargetProperty="Foreground">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlPageTextChromeBlackMediumLowBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement"
                                       Storyboard.TargetProperty="Background">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundChromeWhiteBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement"
                                       Storyboard.TargetProperty="Opacity">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocusedOpacity}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement"
                                       Storyboard.TargetProperty="BorderBrush">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement"
                                       Storyboard.TargetProperty="Foreground">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundChromeBlackHighBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement"
                                       Storyboard.TargetProperty="RequestedTheme">
          <DiscreteObjectKeyFrame KeyTime="0" Value="Light" />
        </ObjectAnimationUsingKeyFrames>
      </Storyboard>
    </VisualState>

    アプリケーションでフォーカス時の色を既定値から変更したい場合、独自のStyleをアプリケーションプロジェクトにて定義し、TextBoxのStyleとして適用します。Styleの定義と適用に関しては自分で調べてください。

    なお、App.xamlのApplication.Resourcesにおいて、ResourceDictionary.ThemeDictionariesでシステムカラーブラシをオーバーライドすることもできますが、もともとシステムカラーというのは、Windows OS側でハイコントラストテーマを選択したときなどにアプリケーションも連動することができるようにするためのものです。よほどの理由がないかぎり、システムカラーをオーバーライドすることは避けたほうが無難です。既定のコントロールの外観や色に関しても、OS設定との統一感やアクセシビリティに配慮されたものとなっています。既定値を捨ててどうしてもカスタマイズしようというのであれば、そういった諸事情にも独自に配慮することが求められます。

    2017年12月2日 16:51

すべての返信

  • 質問するときは開発環境およびターゲット環境のWindows 10バージョンやエディションなども詳しく書くようにしてください。

    UWPでコントロールの外観をカスタマイズする場合、ControlTemplateを使いますが、その前にまずUWP (XAML) における既定の外観定義の仕組みを説明します。

    開発環境が64bit版Windows 10である場合、既定のコントロールの外観は、以下のXAMLファイルにて定義されています。

    %ProgramFiles(x86)%/Windows Kits/10/DesignTime/CommonConfiguration/Neutral/UAP/10.0.*.*/Generic/generic.xaml

    10.0.*.*の数値は開発環境にインストールされているWindows 10 SDKのバージョンに対応します。generic.xamlの中身は、SDKのバージョンによって多少異なります。プロジェクト作成時に選択したターゲットバージョンに応じて使用されるSDKも変わります。

    一例として、TextBox styles and templates - Windows app developmentには、Version 1511 (10.0.10586.0) のgeneric.xamlにおけるTextBoxの既定Styleが記載されています。

    既定のControlTemplateの記述において、フォーカスされたときのVisualStateが記述されています。ここでTextBoxを構成する内部の部品の外観を変更していますが、Windows.Control.ForegroundやBackgroundプロパティは使われず、テーマリソースで定義済みのシステムカラーブラシが使われています。

    <VisualState x:Name="Focused">
      <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter"
                                       Storyboard.TargetProperty="Foreground">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlPageTextChromeBlackMediumLowBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement"
                                       Storyboard.TargetProperty="Background">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundChromeWhiteBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement"
                                       Storyboard.TargetProperty="Opacity">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocusedOpacity}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement"
                                       Storyboard.TargetProperty="BorderBrush">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement"
                                       Storyboard.TargetProperty="Foreground">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundChromeBlackHighBrush}" />
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement"
                                       Storyboard.TargetProperty="RequestedTheme">
          <DiscreteObjectKeyFrame KeyTime="0" Value="Light" />
        </ObjectAnimationUsingKeyFrames>
      </Storyboard>
    </VisualState>

    アプリケーションでフォーカス時の色を既定値から変更したい場合、独自のStyleをアプリケーションプロジェクトにて定義し、TextBoxのStyleとして適用します。Styleの定義と適用に関しては自分で調べてください。

    なお、App.xamlのApplication.Resourcesにおいて、ResourceDictionary.ThemeDictionariesでシステムカラーブラシをオーバーライドすることもできますが、もともとシステムカラーというのは、Windows OS側でハイコントラストテーマを選択したときなどにアプリケーションも連動することができるようにするためのものです。よほどの理由がないかぎり、システムカラーをオーバーライドすることは避けたほうが無難です。既定のコントロールの外観や色に関しても、OS設定との統一感やアクセシビリティに配慮されたものとなっています。既定値を捨ててどうしてもカスタマイズしようというのであれば、そういった諸事情にも独自に配慮することが求められます。

    2017年12月2日 16:51
  • syghさん

    返事が遅くなりすみません。ご回答ありがとうございます。

    まだ、試していませんが上記の方法で解決できそうです。

    以上です、ありがとうございました。

    2017年12月6日 8:35
  • 独自のスタイルを追加して、変更できることを確認しました。

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

    2017年12月7日 9:19