WPF資源
WPF資源系統是一種保管一系列對象(如常用的畫刷、樣式或模版)的簡單辦法,從而使您更容易地復用這些對象。
WPF允許在代碼中以及在標記中的各個位置定義資源(和特定的控件、窗口一起定義,或在整個應用程序中定義)。資源具有如下優點。
- 高效。定義好資源可以在多個地方復用。
- 可維護性。易於修改。
- 適應性。可以動態修改。
資源集合
每個元素都有Resources屬性,該屬性存儲了一個資源字典集合(它是ResourceDictionary類的實例)。資源集合可包含任意類型的對象,並根據字符串編寫索引。
<Window.Resources> <ImageBrush x:Key="TitleBrush" TileMode="Tile" ViewboxUnits="Absolute" Viewport="0 0 32 32"ImageSource="" Opacity="0.3"></ImageBrush> </Window.Resources> <StackPanel> <Button Background="{StaticResource TitleBrush}">Requery</Button> </StackPanel>
資源的層次
每個元素都有自己的資源集合,為了找到期望的資源,WPF在元素樹中進行遞歸搜索。
只要不在同一集合中多次使用相同的資源名,就可以重用資源名稱。
<Window.Resources> <ImageBrush x:Key="TitleBrush" TileMode="Tile" ViewboxUnits="Absolute" Viewport="0 0 32 32" ImageSource="happyface.jpg" Opacity="0.3"></ImageBrush> </Window.Resources> <StackPanel> <Button Background="{StaticResource TitleBrush}">Requery</Button> <Button Background="{DynamicResource TitleBrush}"> <Button.Resources> <ImageBrush x:Key="TitleBrush" TileMode="Tile" ViewboxUnits="Absolute" Viewport="0 0 32 32" ImageSource="abc.jpg" Opacity="0.3"></ImageBrush> </Button.Resources> <Button.Content>Another Titled Button</Button.Content> </Button> </StackPanel>
靜態資源和動態資源
上面的代碼設置后如果執行如下代碼
ImageBrush brush=(ImageBrush)this.Resources["TitleBrush"]; brush.Viewport = new Rect(0,0,5,5);
上述代碼從Window.Resources中檢索畫刷,並改變畫刷平鋪的尺寸,縮小笑臉圖像並壓縮圖像模式使其更加緊湊。因為是靜態資源正常上面的按鈕是不會有變化,
但是這一變化會傳遞給上面的按鈕,更新Viewport屬性。這是因為Brush類繼承自Freezable類。改類有一個基本變化跟蹤特性。這意味着無論何時在WPF中改變畫刷,所有使用該畫刷的控件都會自動更新。靜態資源和動態資源的區別在於靜態資源只從資源集合中獲取對象一次,動態資源每次需要對象時都會重新從資源集合中查找對象。例如:
this.Resources["TitleBrush"] = new SolidColorBrush(Colors.LightBlue);
執行如上代碼,對於靜態資源沒影響,動態資源會發生變化。
使用動態屬性的情況
- 資源具有依賴於系統設置的屬性(如當前Windows操作系統的顏色或字體)。
- 准備通過編程的方式替換對象。(例如實現動態皮膚特性,后台會講到)
非共享資源
正常情況下資源使用的是統一對象實例,這種行為成為共享,如果希望每次都創建一個新的對象可如下設置。x:Shared="False"
<ImageBrush x:Key="TitleBrush" x:Shared="False" TileMode="Tile" ViewboxUnits="Absolute" Viewport="0 0 32 32" ImageSource="happyface.jpg" Opacity="0.3"></ImageBrush>
通過代碼訪問資源
private void txt_TextChanged(object sender, RoutedEventArgs e) { Button cmd = (Button)sender; ImageBrush brush = (ImageBrush)cmd.FindResource("TitleBrush"); }
可使用TryFindResource()代替FindResource()。如果找不到資源會返回null,而不是拋異常。
應用程序資源
窗口不是查找應用程序資源的最后一站,如果在控件或其他容器中知道包含窗口或頁面找不到指定的資源。WPF會繼續查找為應用程序定義的資源。在Visual Studio中,這些資源在App.xaml文件的標記中定義的資源。
<Application x:Class="HelloWpf.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="GridDemoWindow.xaml"> <Application.Resources> <ImageBrush x:Key="TitleBrush" TileMode="Tile" ViewboxUnits="Absolute" Viewport="0 0 32 32" ImageSource="happyface.jpg" Opacity="0.3"></ImageBrush> </Application.Resources> </Application>
應用程序資源為整個應用程序中重用對象提供了一種極佳的方法。
系統資源
當某個元素查找資源時,應用程序資源仍然不是最后一站。如果沒有在應用程序資源中找到所需的資源,元素還會繼續查找系統資源。
系統資源的三個類
- SystemColors 訪問系統顏色設置。
- SystemFonts 訪問字體設置。
- SystemParamerers 封裝了大量的設置列表,這些設置描述了各種屏幕像素的標准尺寸、鍵盤和鼠標設置、屏幕尺寸以及各種圖形效果(如熱跟蹤、陰影以及拖動窗口時顯示窗口內容)是否已經打開。
資源字典
如果希望多個項目中共享資源,可創建資源字典。資源字典只是xaml文檔,除了存儲希望使用的資源外,不做其他任何事情。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ImageBrush x:Key="TitleBrush" TileMode="Tile" ViewboxUnits="Absolute" Viewport="0 0 32 32" ImageSource="happyface.jpg" Opacity="0.3"></ImageBrush> </ResourceDictionary>
使用資源字典將其整合到應用程序資源中。
<Application x:Class="HelloWpf.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="GridDemoWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="AppBrushs.xaml"></ResourceDictionary> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
