zoukankan      html  css  js  c++  java
  • Binding的数据转换

      当Source端Path所关联的数据与Target端目标属性数据类型不一致时,就需要进行转换。如果是基本类型的转换,WPF就替我们做了,但下面几种情况,就需要我们自己写数据转换器:

    • Source里的数据是Y、N和X三个值,UI上对应的是CheckBox,需要把三个值映射为它的IsCheck属性;
    • 当TextBox里已经输入了文字时用于登录的Button才会出现,这是需要把String转换为Bool;
    • Source里的数据是枚举或String,UI上对应的是显示头像的Image控件,这时需要把值转换为图片的URI。

      手动编写转换器就要创建一个类并继承IValueConverter接口。IValueConverter接口定义如下:

        //     提供一种将自定义逻辑应用于绑定的方式。
        public interface IValueConverter
        {
            // 摘要: 
            //     转换值。
            //
            // 参数: 
            //   value:
            //     绑定源生成的值。
            //
            //   targetType:
            //     绑定目标属性的类型。
            //
            //   parameter:
            //     要使用的转换器参数。
            //
            //   culture:
            //     要用在转换器中的区域性。
            //
            // 返回结果: 
            //     转换后的值。 如果该方法返回 null,则使用有效的 null 值。
            object Convert(object value, Type targetType, object parameter, CultureInfo culture);
            //
            // 摘要: 
            //     转换值。
            //
            // 参数: 
            //   value:
            //     绑定目标生成的值。
            //
            //   targetType:
            //     要转换到的类型。
            //
            //   parameter:
            //     要使用的转换器参数。
            //
            //   culture:
            //     要用在转换器中的区域性。
            //
            // 返回结果: 
            //     转换后的值。 如果该方法返回 null,则使用有效的 null 值。
            object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
        }

      当数据从Binding的Source流向Target时,Covnert方法被调用,反之,ConvertBack方法被调用。这个两个方法参数列表一样,第一个参数为Object,保证了Convert的重用性,可在方法主体内进行类型判断;第二参数用于确定方法的返回类型;第三个参数用于把额外的信息传入方法,若需要传递多个信息则可把信息放入到一个集合对象来传入方法。

      Binding对象的Mode会影响这两个方法的调用。如果Mode为TwoWay则两个方法都有可能被调用,如果Mode为OneWay则只有Convert方法会被调用。

      下面我们模拟一个信息提交的需求,UI上一个TextBox和Button,当TextBox的Text不为空时Button才可用,XAML代码如下:

    <Window x:Class="WpfApplication3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="150" Width="225">
        <StackPanel>
            <TextBox x:Name="txtName" Margin="10"></TextBox>
            <Button x:Name="btnOK" Content="提交" IsEnabled="False" Margin="10" Click="btnOK_Click"></Button>
        </StackPanel>
    </Window>

      编写自己的Converter,代码如下:

        public class CommitBindingConverter:IValueConverter
        {
    
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                string s = value as string;
                if (string.IsNullOrEmpty(s))
                    return false;
                return true;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }

      在窗体的构造函数里设置Bingding,代码如下:

     Binding b = new Binding("Text") { Source = this.txtName };
     b.Converter = new CommitBindingConverter();
     this.btnOK.SetBinding(Button.IsEnabledProperty, b);

      运行程序,就会发现只有TextBox的Text不为空时,Button才可用。

  • 相关阅读:
    论 设计模式及项目架构的作用
    Linux根据进程号查找其程序文件路径 及 lsof 命令使用
    Synchronized 原理
    Seata 中类SPI使用机制分析
    redisson spring boot starter 做分布式锁
    TTFB 时间过长
    ShardingSphere Hint模式 SpringBoot + Mybatis
    Core源码(十三)Stack和ConcurrentStack
    C#源码(十二) HashSet
    Core源码(十一)Queue
  • 原文地址:https://www.cnblogs.com/yijiaoyingbi/p/4867292.html
Copyright © 2011-2022 走看看