WPF 配色を外部ファイル化する
「app.configに設定した色をコントロールの背景色に使う」とかそういうイメージ。
アイデア
- app.configにて色を16進数で指定。
- app.configにある色情報をアクセッサクラス(Pallet.vb)を作成。
- リソースファイル(xaml)にて、Palletクラスをインスタンス。色を取り出し単色ブラシにする。 このリソースファイルをTheme.xamlとして、他のリソースから参照する。
app.configにて色を16進数で指定
特筆すべきことはありません。こんな感じで指定するだけ。
… <setting name="PageBackgroundColor" serializeAs="String"> <value>#F5F5F5</value> </setting> …
パレットクラスを作る
app.configで設定した色情報はあくまでもString型なので、これをColor構造体に変換し扱いやすいものに変える。
Public Class Pallet Public Sub New() Me.PageBackgroundColor = My.Settings.PageBackgroundColor.ToColor End Sub ''' <summary> ''' ページ背景色 ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public Property PageBackgroundColor As System.Windows.Media.Color End Class
型変換は拡張メソッドで定義して、「String.ToColor」と記述できるようにしてやりましょう。なお色名指定には対応しておりません。
Public Module StringExtension Private Const RGB_PATTERN As String = "^#(?<r>[0-9A-Fa-f]{2})(?<g>[0-9A-Fa-f]{2})(?<b>[0-9A-Fa-f]{2})$" Private Const ARGB_PATTERN As String = "^#(?<a>[0-9A-Fa-f]{2})(?<r>[0-9A-Fa-f]{2})(?<g>[0-9A-Fa-f]{2})(?<b>[0-9A-Fa-f]{2})$" <Extension()> Public Function ToColor(source As String) As Color Try Dim a As Integer = 255 Dim r As Integer = 255 Dim g As Integer = 255 Dim b As Integer = 255 If Regex.IsMatch(source, RGB_PATTERN) Then Dim m As Match = Regex.Match(source, RGB_PATTERN) r = HexToInt(m.Groups("r").Value) g = HexToInt(m.Groups("g").Value) b = HexToInt(m.Groups("b").Value) ElseIf Regex.IsMatch(source, ARGB_PATTERN) Then Dim m As Match = Regex.Match(source, ARGB_PATTERN) a = HexToInt(m.Groups("a").Value) r = HexToInt(m.Groups("r").Value) g = HexToInt(m.Groups("g").Value) b = HexToInt(m.Groups("b").Value) End If Return Color.FromArgb(a, r, g, b) Catch ex As Exception Return Color.FromRgb(255, 255, 255) End Try End Function Private Function HexToInt(s As String) As Integer Return Convert.ToInt32(s, 16) End Function End Module
テーマリソースディクショナリを作る
特筆すべきことなし。名前空間の「theme」は適宜ご自分の環境に変えてお使いください。(Themeクラスの正式名が「Prism.UI.Extension.Theme」の場合、以下のようになる)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:theme="clr-namespace:Prism.UI.Extension.Theme"> <theme:Pallet x:Key="pallet" /> <SolidColorBrush x:Key="PageBackgroundBrush" Color="{Binding PageBackgroundColor, Source={StaticResource pallet}}" /> </ResourceDictionary>
あとは使うだけ
Sourceの記述は適宜ご自分の環境に変えてお使いください。(テーマリソースディクショナリが「Prism.UI.Extension」ライブラリのパス「/Theme/Resources/Theme.xaml」にある場合、以下のようになる)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/Prism.UI.Extension;component/Theme/Resources/Theme.xaml" /> </ResourceDictionary.MergedDictionaries> … </ResourceDictionary>
おまけ
設定色は少ない方が管理が楽なので、こんなことをするといいかも。
- 文字色は背景色の明度を判定して動的に判定させることで省略する。
- フォーカス時のハイライトカラーは透明度のレイヤーをかぶせて表現することで省略する。