WPF跨程序集共享樣式(跨程序集隔離樣式和代碼)
前記:WPF中的樣式使用一般分為兩種Statci和Dynamic.兩者的區別可以理解為,前者在運行的時候已經確定了樣式的風格,而後者可以根據資源在運行時的修改而修改也可以使用那些在運行時才存在的資源。
背景:有時候我們會將樣式的資源和XAML頁面代碼分離,有時候也希望同一個資源可以在多個Application中使用;另外還有一個更致命的問題,如果我們在很多地方都寫了重復的樣式,突然有一天我們要修改,那豈不是要一個一個地方進行修改,那工作量實在不敢想象。好在WPF中提供了解決這個問題的好方法,那就是ComponentResourceKey(定義或引用基於外部程序集中的類名以及一個附加標識符的資源鍵。
發功(此功一共分為3步):
1.定義一個ComponentResourceKey需要的類型,如下:
public class CustomResources { public static ComponentResourceKey DesertBrushKey { get { return new ComponentResourceKey(typeof(CustomResources), "DesertBrush"); } } }
類名隨意,其實類中可以沒有東西,我們的內容稍後解釋。
2.添加generic.xaml文件(如果你有可以忽略)、添加資源(直接寫Dictionary字典或者直接寫在generic.xaml中)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WpfApplication9"> <ImageBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomResources},ResourceId=DesertBrush}" ImageSource="/WpfApplication9;component/Desert.jpg"></ImageBrush> </ResourceDictionary>
添加對命名空間的引用,然後寫一個ImageBrush樣式資源。關鍵來了,Key不是一個字符串,而是一個很復雜的不知道什麽東東的東東。
解釋: 關於Key設置的語法,往下看,在這裏我們使用的是詳細版的語法,ComponentResourceKey固定關鍵字,TypeInTargetAssembly即為我們創建的類型(x:Type為WPF提供的),ResourceID就是之前我們習慣設置的Key(名稱隨意)。
XAML設置鍵,精簡版:
<object x:Key="{ComponentResourceKey {x:Type targetTypeName}, targetID}" .../>
XAML設置鍵,詳細版:
<object x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type targetTypeName}, ResourceID=targetID}" .../>
請求資源,精簡版:
<object property="{DynamicResource {ComponentResourceKey {x:Type targetTypeName}, targetID}}" .../>
請求資源,詳細版:
<object property="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type targetTypeName}, ResourceID=targetID}}" .../>
註意:generic.xaml路徑為Themes/generic.xaml
3.使用資源
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:res="clr-namespace:WpfApplication9;assembly=WpfApplication9" Title="MainWindow" Height="350" Width="525"> <Grid> <Button Background="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type res:CustomResources}, ResourceId=DesertBrush}}"></Button> </Grid> </Window>
上述XAML文件和資源不在同一個程序,所以首先添加對上一個程序的引用,然後在XAML中添加對命名空間的引用,然後在Button的Background上使用我們的資源。
解釋:資源的使用語法見上文,ComponentResoruceKey固定關鍵字,TypeInTargetAssembly也是我們創建的類,最後ResourceId同樣為我們在資源中定義的ResourceId。
說在最後:其實本文還沒完,還有很有用的一點,是不是覺得使用方式很復雜,是不是覺得類中的代碼到底是幹嘛的呢,開始解答。
鑒於使用資源的方法過於繁瑣,可以在類中添加一個靜態的屬性類型同樣為ComponentResoruceKey,返回值為實例化的ComponentResoruceKey,第一個參數為我們的類的類型,第二個參數為資源中的ResourceId的值,然後你就可以這麽使用:
<Button Background="{DynamicResource {x:Static res:CustomResources.DesertBrushKey}}"></Button>
原諒我在最後才拿出簡單的使用方法,我也是為大家好呢。
WPF跨程序集共享樣式(跨程序集隔離樣式和代碼)