XAML 給資源起個好名字 用 StaticResource 起一個別名

本文來和大家聊一下關於 XAML 資源的定義的事情,和開發技術關係不大,更多的是開發的思路

在稍微大一點的項目裏,肯定 XAML 資源是少不了的。對於 XAML 資源,行業裏討論多(非小白討論)的是關於資源的複用和初始化時機,加載時機的問題。本文聊的是資源的複用以及變更資源的開發模式

如果團隊裏有一位開發者是命名高手,那麼問題將特別小。或者說這個項目只有一位開發者在開發,也不需要後續維護,那這個問題也特別的小。然而在很多團隊裏面,都有很多開發者,同時開發者的命名能力也有一定的差距

如果沒有給資源一個好的命名,自然,每次用起來的時候,都會遇到一個問題,那就是某個資源找不到的問題。一旦找不到資源,自然就只能重新定義資源了。或者說我以爲某個資源是我此模塊能用的,然而此資源卻非通用設計,也許下個版本就被更改,於是我的模塊就因爲某個資源的變更而挖坑

如下面的例子:

我需要開發一個應用,此應用有多個頁面組合。由於技術側的問題,我不能將每個頁面都使用相同的控件,需要採用不同的控件。但是爲了界面的美觀,儘管使用的不同的控件,依然也需要保持相似頁面佈局方式。按照慣例,假定定義頁面的內邊距,假設默認的頁邊距是 12 單位大小,定義爲資源可以如何寫?如以下的資源定義

<Thickness x:Key="TwelveThickness">12,12,12,12</Thickness>

可以看到,定義資源爲 12 單位的 Thickness 有點過於具體了。如果後續設計師想改爲 16 個單位呢?那此時就是一個選擇了,要麼將此資源改爲 16 的值,但是保留 TwelveThickness 這個詞,讓其他的開發者看到這裏雖然寫着是 Twelve 但實際上是 16 個單位。要麼就是改值和改資源名,說不定就是炸魚的改動了。要麼就是再新加一個資源名,也許這樣垃圾就加一了

如果有一個具體的命名呢?命名和數值無關的呢?例如命名爲 MainPagePadding 呢?這個感覺是不錯的,給主頁面使用的 Padding 值。但是不夠抽象,如果我用的是 FxxPage 的呢,這個也需要一個內邊距,那用哪個資源好呢

如果定義的資源命名是 DefaultPagePadding 呢,或者 PagePadding 呢,是不是就更抽象了一層,不僅 MainPage 能用,也合適 FxxPage 使用

但是定義的抽象等級,除非是命名高手,否則一次性叫對一個命名還是很有難度的。而有一些資源,又是十分衝突的。既是非常通用的,卻也許會被變更。例如顏色,定義顏色畫刷的時候,資源的重複存在的問題核心就是開發模式上的尋找困難和被其他開發者更改帶來的鍋,在性能上的問題就是非託管資源的佔用增加,沒有複用原有的畫刷。但是顏色的定義,是會在迭代被變更的

從技術側的一個解決方法是採用 StaticResource 來進行資源的引用,相當於給資源一個別名的方式。再定義一個資源,引用原先的資源

例如有一個紅色是默認的主題紅色,最好的定義是 Brush.SolidColorBrush.RedThemeBrush 的資源名。然而此資源名特別具體,如果作爲主頁面的背景色的時候,此時將會因爲太過具體而不合適。畢竟後續如果我還有其他的頁面,似乎用來做背景的,耦合了具體的紅主題色是不合適的

那如果再定義一個畫刷主題,稱爲 MainPageBackgroundBrush 呢?自然,重複定義的畫刷就是重複的資源,不合適

好在可以使用 StaticResource 的方式,使用靜態資源引用,從而讓資源被重新定向,如下面代碼,定義了一個主題顏色

        <SolidColorBrush x:Key="Brush.SolidColorBrush.RedThemeBrush" Color="#FFC10606"/>

接下來可以採用 StaticResource 引用此顏色,定義一個默認的頁面的背景畫刷

        <StaticResource x:Key="DefaultPageBackgroundBrush" ResourceKey="Brush.SolidColorBrush.RedThemeBrush"/>

再定義具體的主頁面的背景畫刷

        <StaticResource x:Key="MainPageBackgroundBrush" ResourceKey="DefaultPageBackgroundBrush"/>

於是在引用的時候,可以在主頁面,只引用主頁面的背景畫刷

        <Grid x:Name="MainPage" Background="{StaticResource MainPageBackgroundBrush}"></Grid>

這樣做的一個優勢在於,讓資源的定義是一層層定義的。解決了開發側的重複資源定義,又想資源重複定義方便改動的時候相互不影響,又想着不重複定義方便要改可以一起改的問題

如以上的代碼,相當於將資源的定義分爲三層。最底層是 Brush.SolidColorBrush.RedThemeBrush 定義一個和業務無關的畫刷,第二層是 DefaultPageBackgroundBrush 定義和頁面有關的默認畫刷,最上層是 MainPageBackgroundBrush 定義和主頁面相關的畫刷

這些畫刷都是相同的一個資源,只是靠 StaticResource 進行引用

如果後續準備改主頁面的畫刷,而其他的頁面保持不動。那麼可以明確瞭解到,只需要改 MainPageBackgroundBrush 的資源值即可,影響不到其他的頁面。而如果期望是全部頁面的背景色都換成某個其他的顏色,只需要改 DefaultPageBackgroundBrush 即可。如果是設計師想要改整個應用的紅色主題色,那就改 Brush.SolidColorBrush.RedThemeBrush 的顏色

如此的設計可以比較方便解決比較大的項目的資源引用問題。核心的思想就是依靠引用的方式,將資源的定義分層,按照抽象的不同,分爲不同層的定義。定義資源的命名方式最好都是一組一組的,一個抽象層裏面有很多組,每一組之間的命名都是非常相似的。如此就很方便資源的管理。這只是一個思想,不使用 StaticResource 也可以,如換成綁定的方式也可以

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章