3

WPF テーマ、スキン、スタイルなどについて多くのことを読みましたが、まだ達成できないことがあります。

各テーマ ファイル (Aero.NormalColor.xaml、Luna.NormalColor.xaml、または Aero2.NormalColor.xaml) に異なるスタイルを設定することで、OS テーマに応じてスタイル設定されたカスタム コントロールがあります。 .

App.xaml にテーマをロード/強制しません。各コントロール (ボタンなど) は、OS テーマに応じてスタイルを維持します。したがって、XP では XP ボタン、Windows 7 では Win7 ボタン、Windows 8 では Win8 ボタンが表示されます。

また、さまざまな通常の wpf コントロールの「名前付き」(明示的な x:Key) スタイルを含む App.xaml に読み込まれる ResourceDictionaries もあります。それらは次のようになります。

<Style x:Key="BlackComboBox" TargetType="{x:Type ComboBox}"></Style>

そして、私はそれらをこのように使用します

<ComboBox Style="{StaticResource BlackComboBox}"></ComboBox>

したがって、今のところ、私の BlackComboBox はすべての Windows (XP/7/8) で同じです。

私が達成しようとしているのは、コントロールをサブクラス化することなく、OS テーマに応じてこれらの通常のコントロールに異なるスタイルを設定することです (OS 固有のコントロールが必要な各コントロールにサブクラスを設定するのはやり過ぎだと思います)。そのため、BlackComboBox は OS ごとに異なる可能性があります。

既に同じキーを持つスタイルをテーマ ファイルに入れようとしましたが、うまくいかないようです。

目的の OS バージョンのスタイルを含む別の ResourceDictionary を実行時にロードすることを考えました。

  • しかし、それは醜い解決策のように見えます。
  • System.Environment.OSVersion をチェックする必要はありません。
  • また、テーマに依存するのではなく、OS に依存します。

私にとって最良の方法は、ResourceDictionaries のスタイルをオーバーライドするテーマ ファイルに「名前付き」スタイルを設定できるようです。

助けてくれてありがとう!

4

1 に答える 1

1

これを行う唯一の方法は、カスタム コントロールを作成し、テーマごとに異なる外観を持たせたい場合と同じように、テーマごとにリソース ディクショナリを作成することだと思います。次に、ComboBox のそれぞれにスタイルを作成し、各テーマのリソース ディクショナリの x:Key に同じ値を使用して、スタイルの x:Key として ResourceKey 派生クラス (ComponentResourceKey など) を提供します。次に、Style を参照するときに、その ResourceKey に対して DynamicResource を使用します。

したがって、簡単な例は、新しい WpfApplication を作成することです (たとえば、WpfResourceKeys という名前を付けました)。この場合、メイン アセンブリにテーマ リソース ディクショナリを配置するので、AssemblyInfo.csに移動し、ThemeInfoの 1 番目のパラメーター (つまり、themeDictionaryLocation ) をSourceAssemblyに設定します。

次に、「themes」という名前のフォルダーを作成し、その中に、サポートする各テーマのリソース ディクショナリを作成します。たとえば、 aero.normalcolor.xamlaero2.normalcolor.xamlluna.normalcolor.xamlclassic.xamlなど.

各 ResourceDictionary で、ComboBox または任意のコントロールのスタイルを定義し、同じ ResourceKey のx:Keyを指定します。最も簡単に使用できるのはComponentResourceKeyです。私の場合は、背景を設定するだけなので TextBox を使用します。これは、各テーマに定義されたテンプレートに関係なく適用されます。例えば

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:local="clr-namespace:WpfResourceKeys"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="TextBox" 
        x:Key="{ComponentResourceKey 
            ResourceId=Foo, 
            TypeInTargetAssembly={x:Type local:MainWindow}}">
        <Setter Property="Background" Value="Purple" />
    </Style>
</ResourceDictionary>

私の場合、これを各テーマの xaml ファイルに入れただけですが、Background セッターがテストするために異なる値を使用しています。したがって、私の aero2.normalcolor.xaml ではセッターの値は Purple で、classic.xaml ではセッターの値は Orange でした。Windows 8 で既定のテーマを使用してテストを実行すると、TextBox は紫になりますが、ハイ コントラスト テーマのいずれかに切り替えると、TextBox はオレンジ色になります。

次に、それを参照する場所では、ウィンドウまたは app.xaml のリソース内で Style を定義しないため、StaticResource の代わりに DynamicResource を使用します (フレームワークが OS を考慮してそれを見つけられるようにするため)テーマ)。

<Window x:Class="WpfResourceKeys.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfResourceKeys"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBox Style="{DynamicResource ResourceKey={ComponentResourceKey 
            ResourceId=Foo, 
            TypeInTargetAssembly={x:Type local:MainWindow}}}" Text="ABC" />
    </Grid>

テーマ ディクショナリでの定義方法と同等のリソース キーを使用していることを確認する必要があります。ComponentResourceKey の場合は、ResourceId と TypeInTargetAssembly が同等であることを意味します。

于 2013-05-29T13:24:58.513 に答える