1. 程式人生 > 其它 >Binding(三):資源和ValueConverter

Binding(三):資源和ValueConverter

這節講資源和值轉換器(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}"

第三個引數主要是提供一些轉換上的輔助,帶給我們用於轉換的更多的資訊,第四個我個人理解多用在國際化上,我們可以根據這個引數獲取當前的語言環境,這兩個都不是擴充套件屬性,都不能使用標記擴充套件。