Binding(三):资源和ValueConverter

2021年09月15日 阅读数:1
这篇文章主要向大家介绍Binding(三):资源和ValueConverter,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

    这节讲资源和值转换器(ValueConverter)。this

资源spa

    在XAML中,咱们想要使用外部的数据或者类,须要引入其命名空间,而后将其定义为XAML页面的资源,供给控件使用,或者咱们须要封装一个共用的样式,一样也须要定义成资源来使用,下面咱们看一下如何定义一个资源:3d

<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对象。code

    那定义资源后,如何使用呢,这就又要用到标记扩展语法了,请看下面的代码:对象

<StackPanel>
    <Button Content="{StaticResource show}" 
            Style="{StaticResource styleShow}" />
</StackPanel>

  

    使用StaticResource命令获取一个资源,后面接资源的key,我给这个button引入了上方定义的资源,运行效果以下:blog

    另外,除了StaticResource,还有一个DynamicResource命令,StaticResource在程序一开始加载一次,若是资源中途变更,是不会再更新到使用它的控件上的,而DynamicResource则相反,它会跟着资源的更新而更新,因此要合理使用二者。接口

    后台代码中,声明资源和获取资源就简单多了,代码以下:资源

this.Resources.Add("show", "我是个资源");//定义资源
object data = this.Resources["show"];
this.FindResource("show");

    后台无非就是操做键值对集合,而且咱们也可使用FindResource方法来寻找资源。字符串

 

ValueConverterget

    上节咱们提到一个情景,将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}"

     第三个参数主要是提供一些转换上的辅助,带给咱们用于转换的更多的信息,第四个我我的理解多用在国际化上,咱们能够根据这个参数获取当前的语言环境,这两个都不是扩展属性,都不能使用标记扩展。