這節講資源和值轉換器(ValueConverter)。
資源
在XAML中,我們想要使用外部的資料或者類,需要引入其名稱空間,然後將其定義為XAML頁面的資源,供給控制元件使用,或者我們需要封裝一個共用的樣式,同樣也需要定義成資源來使用,下面我們看一下如何定義一個資源:
<Window.Resources> <ResourceDictionary> <sys:String x:Key="show">我是一個資源</sys:String> <Style x:Key="styleShow" TargetType="Button"> <Setter Property="Background" Value="Purple" /> <Setter Property="Foreground" Value="White" /> </Style> </ResourceDictionary> </Window.Resources>
資源的型別是ResourceDictionary,顧名思義,資源是用鍵值對儲存的,所以定義資源時需要給它個key,這個Key的value則根據定義資源的不同千變萬化了,像上方程式碼中,定義一個string資源,它的value就是一個普通的字串,定義一個樣式資源,它的value就是一個定義樣式的setter物件。
那定義資源後,如何使用呢,這就又要用到標記擴充套件語法了,請看下面的程式碼:
<StackPanel> <Button Content="{StaticResource show}" Style="{StaticResource styleShow}" /> </StackPanel>
使用StaticResource命令獲取一個資源,後面接資源的key,我給這個button引入了上方定義的資源,執行效果如下:
另外,除了StaticResource,還有一個DynamicResource命令,StaticResource在程式一開始載入一次,如果資源中途變動,是不會再更新到使用它的控制元件上的,而DynamicResource則相反,它會跟著資源的更新而更新,所以要合理使用兩者。
後臺程式碼中,宣告資源和獲取資源就簡單多了,程式碼如下:
this.Resources.Add("show", "我是個資源");//定義資源 object data = this.Resources["show"]; this.FindResource("show");
後臺無非就是操作鍵值對集合,並且我們也可以使用FindResource方法來尋找資源。
ValueConverter
上節我們提到一個情景,將Button的顯示與隱藏跟CheckBox是否選中做繫結,這個就需要用到我們接下來講的ValueConverter。
首先我們需要新建一個類,程式碼如下:
class BoolToVisibilityConvert : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) return DependencyProperty.UnsetValue; if ((bool)value == true) { return Visibility.Visible; } else return Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) return false; if ((Visibility)value == Visibility.Visible) { return true; } else return false; } }
使用ValueConverter需要實現IValueConverter介面,其內部有兩個方法,Convert和ConvertBack。我們在使用Binding繫結資料的時候,當遇到源屬性和目標控制元件需要的型別不一致的,就可以使用ValueConverter,它就相當於一個橋,當資料從源到目標控制元件時,需要走Convert方法,我們在這個方法裡邊就可以自定義轉換邏輯,當資料從目標控制元件到源時,需要走ConvertBack方法,我們可以在這裡邊自定義迴轉邏輯。
上述程式碼中,我就實現了Button的Visibility屬性和bool之間的轉換,下面我們需要將這個類作為資源,載入XAML頁面,讓Button使用,程式碼如下:
<Window.Resources> <ResourceDictionary> <local:BoolToVisibilityConvert x:Key="B2V" /> </ResourceDictionary> </Window.Resources>
這個ValueConverter類的名稱空間就是當前專案的名稱空間,所以直接使用local即可,local是預設代表當前程式碼的名稱空間簡稱,具體相關XAML名稱空間的知識參見前文:剖析XAML語言。
XAML程式碼如下:
<StackPanel> <CheckBox x:Name="CB" Click="CheckBox_Click" /> <Button Content="{StaticResource show}" Style="{StaticResource styleShow}" Visibility="{Binding ElementName=CB, Path=IsChecked, Converter={StaticResource B2V}}" /> </StackPanel>
程式執行效果如下:
最後來解釋一下轉換方法的四個引數,第一個就是資料,我們要轉換的值就是它,第二個引數是目標型別,當從bool轉換為Visibility時,這個引數就是Visibility,反之則是bool,第三個引數是轉換引數,可以在標記擴充套件中定義,第四個是文化引數,也是可以在擴充套件標記中定義,詳見如下:
Visibility="{Binding ElementName=CB, Path=IsChecked, Converter={StaticResource B2V},ConverterParameter=true,ConverterCulture=zh-CN}"
第三個引數主要是提供一些轉換上的輔助,帶給我們用於轉換的更多的資訊,第四個我個人理解多用在國際化上,我們可以根據這個引數獲取當前的語言環境,這兩個都不是擴充套件屬性,都不能使用標記擴充套件。