WPFのコンボボックスの背景色について

TreeListView上でコンボボックスを利用するときにフォーカスのあるコンボボックスの色をイベントで変えようとしたけど上手くいかなかった。

色々と調べているとXaml側のテンプレートをいじる必要があるみたいだったので、いろいろとやってみた。

とりあえず、コンボボックスをデザイナに配置し、コンボボックスを選択した状態で「右クリック」->「テンプレートの編集」ー>「コピーして編集」を選択する。


リソースの名前は後でも変更できるのと、自動で作成されるXAMLの場所も移動できるので一旦は初期のままにして「OK」を押す。


ものすごく長いリソースがWindow.Resourceの中に作成される


このリソースの中でBackgroundを管理している箇所のStyleを変更すれば変えることができる。具体的には下記の画像の部分。
※編集可能なコンボボックスを使っているときは「ComboBox.Static.Editable.Background」を変更すればよいと思われる。




今回の場合は、フォーカスの移動によって背景色を変更したかったので、「ComboBox.Static.Background」、「ComboBox.MouseOver.Background」をデザイナ上は「Transparent」に設定しておいて、プログラムからGotFocusイベントとLostFocusイベントを利用して変更している。

=== ソース抜粋1 ===
            // 選択中の背景色を設定する
            this.GotFocus += SetSelectionBackgroundColor;
            // 選択中の背景色を初期値にもどす
            this.LostFocus += ClearSelectionBackgroundColor;
==============

=== ソース抜粋2 ===

        /// <summary>
        /// フォーカス取得時の背景色
        /// </summary>
        public Brush SelectionBackgroundColor = new SolidColorBrush(Color.FromArgb(255, 250, 250, 0));

        /// <summary>
        /// 選択中のコンボボックスの背景色を設定
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetSelectionBackgroundColor(object sender, RoutedEventArgs e)
        {
            var grid = this.Template.FindName("templateRoot", this) as Grid;
            if (grid != null)
                grid.Background = SelectionBackgroundColor;
        }

        /// <summary>
        /// 選択中のコンボボックスの背景色を初期化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ClearSelectionBackgroundColor(object sender, RoutedEventArgs e)
        {
            var grid = this.Template.FindName("templateRoot", this) as Grid;
            if (grid != null)
                grid.Background = null;
        }

=============
※templateRootは先ほどデザイナから自動生成されたXAMLの中で「ComboBoxTemplate」というControlTemplateがあるが、その中のGridのこと。
 なのでコンボボックスを構成する各コントロールを配置している元のGridの背景色を変更しているだけ。逆に言うとコンボボックスをどうやって作っているのかがControlTemplateを見ればわかる。


後はこの作成したリソースをコンボボックスのStyleに適用すればよい。

=== ソース抜粋3 ===
<ComboBox  ItemsSource="{Binding PriorityList, Mode=TwoWay}"
DisplayMemberPath="Name" SelectedValuePath="PriorityNo"
SelectedValue="{Binding SelectedPriorityNo}" Style="{StaticResource ComboBoxStyle1}">

=============

Window.Resourceに配置すると他のWindowでは利用できなくなるので、App.Xamlに配置すれば他のWindowから利用できる。
App.Xamlが長くなりすぎるのであれば、別のリソースディクショナリに作成して、App.Xamlは「ResourceDictionary.MergedDictionaries」でリソースの指定をすればよい。

<適用した例>


0 件のコメント:

コメントを投稿

PowerShellでEdgeを自動化(インストール不要。参考:郵便追跡サービス自動操作)

1.経緯について  RPAのソフトをインストールできないので、これまでVBSでCreateObjectでブラウザの自動操作をすることがたまにあった。 ※いざというときの手札として持っているだけで安心感が段違い  見た目上IEがインストールされていなくても、CreateObject...