簡體   English   中英

樣式WPF正常控制取決於Windows主題

[英]Style WPF normal Control depending on Windows Theme

我已經閱讀了很多關於WPF主題,皮膚,風格等的東西...但是仍然有一些我無法實現的東西。

我有自定義控件,根據操作系統主題設置樣式,在每個主題文件(Aero.NormalColor.xaml,Luna.NormalColor.xaml或Aero2.NormalColor.xaml)中使用不同的樣式,這個工作就像一個魅力。

我沒有加載/強制我的App.xaml中的任何主題,每個控件(如按鈕)保持樣式取決於操作系統主題。 所以我看到XP上的XP按鈕,Windows 7上的Win7按鈕和Windows 8上的Win8按鈕。

我還有在App.xaml中加載的ResourceDictionaries,它包含不同普通wpf控件的“命名”(顯式x:Key)樣式。 它們看起來像這樣:

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

我就像這樣使用它們

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

所以現在,我的BlackComboBox在每個Windows(XP / 7/8)上都是一樣的。

我試圖實現的是根據操作系統主題為這些普通控件設置不同的樣式,而不必對控件進行子類化(我認為為每個需要特定操作系統的控件創建一個子類會有點過分),所以BlackComboBox在每個操作系統上都可能不同。

我已經嘗試在主題文件中添加具有相同鍵的樣式,但這似乎不起作用。

我想過在運行時加載一個包含所需操作系統版本樣式的不同ResourceDictionary:

  • 但它看起來像一個丑陋的解決方案。
  • 我不喜歡檢查System.Environment.OSVersion。
  • 它不會依賴於主題,而是依賴於操作系統。

對我來說,最好的方法似乎是能夠在主題文件中使用“命名”樣式,這樣可以覆蓋ResourceDictionaries中的那個。

謝謝您的幫助!

我相信這樣做的唯一方法是為每個主題創建資源字典,就像創建自定義控件並希望每個主題具有不同的外觀一樣。 然后,您將為每個ComboBox創建一個Style,並提供一個ResourceKey派生類(例如ComponentResourceKey)作為Style的x:Key,在每個主題的資源字典中使用相同的x:Key值。 然后,當您引用Style時,您將使用DynamicResource到該ResourceKey。

因此,一個簡化的例子是創建一個新的WpfApplication(例如我將其命名為WpfResourceKeys)。 在這種情況下,我將把主題資源字典放在主程序集中,所以我進入AssemblyInfo.cs並將ThemeInfo的第一個參數(即themeDictionaryLocation )設置為SourceAssembly

然后創建一個名為“ themes ”的文件夾,並在其中為您要支持的每個主題創建一個資源字典.Eg aero.normalcolor.xamlaero2.normalcolor.xamlluna.normalcolor.xamlclassic.xaml等。

在每個ResourceDictionary中為ComboBox定義一個Style或你想要的任何控件,並給它一個相同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文件中,但背景設置器的值不同,以測試它。 所以在我的aero2.normalcolor.xaml中,setter值為Purple,而在classic.xaml中,setter值為Orange。 當我在Windows 8中使用默認主題運行我的測試時,TextBox是紫色的,但如果我切換到高對比度主題之一,TextBox就是橙色。

然后在你要引用的地方你將使用DynamicResource而不是StaticResource,因為你不會在窗口或app.xaml的資源中定義Style(因為你希望框架在考慮操作系統時找到它)主題)。

<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是等效的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM