Binding的数据转换
来源:互联网 发布:ubuntu 一键lamp 编辑:程序博客网 时间:2024/06/06 11:38
Binding有一种机制成为数据转换(Data Convert),当Source端Path所关联数据与Target端目标属性数据类型不一致时,我们可以添加数据转换器(Data Converter)。
手写Converter的方式是创建一个类并让这个类实现IValueConverter接口。IValueConverter接口定义如下:
public interface IValueConverter { object Convert(object value, Type targetType, object parameter, CultureInfo culture); object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture); }
当数据从Binding的Source流向Target时,Convert方法将被调用;反之,当Binding的Target流向Source时,ConverterBack将被调用。这两个方法的参数列表一模一样:第一个参数是object,最大限度地保证了Converter的重要性(可以在方法体内对实际类型进行判断);第二个参数用于确定方法的返回类型(个人认为形参名字叫outputType比targetType要好,可以避免与Binding的Target混淆);第三个参数用于把额外的信息传入方法,若需要传递多个信息则可以把信息放入一个集合对象来传入方法。
Binding对象的Mode属性会影响到这两个方法的调用。如果Mode为TwoWay或Default行为与TwoWay一致则两个方法都可能被调用;如果Mode为OneWay或Default行为与OneWay一致则可能只有Convert方法会被调用;其他情况同理。
下面的例子是一个Converter的综合实例,程序的用途是在列表中向玩家显示一些军用分级的状态。
首先创建几个自定义数据类型:
public enum Category { Bomber, Fighter } public enum State { Available, Locked, Unknown } public class Plane { public Category Category { get; set; } public string Name { get; set; } public State State { get; set; } }
在UI里Plane的Category属性呗映射为轰炸机或者战斗机的图标,把这两个图标加入到该项目中。
同时飞机的State属性在UI里被映射为CheckBox。因为存在以上两个映射关系,我们需要提供两个Converter:一个是由Category类型单向转换为string类型(XAML编译器能够把string对象解析成图片资源URI),另一个是在State与bool?类型之间双向转换。
public class CategoryToSourceConverter:IValueConverter { //将Category转换为Uri图片资源 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Category c = (Category)value; switch (c) { case Category.Bomber: return @"\Icons\Bomber.jpg"; case Category.Fighter: return @"\Icons\Plane.jpg"; default: return null; } } //不会被调用 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); }
public class StateToNullableBoolConverter:IValueConverter { //将State转换为bool? public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { State s = (State)value; switch (s) { case State.Available: return true; case State.Locked: return false; case State.Unknown: default: return null; } } //将bool?转换为State bool? 可以为 null 的类型可以包含三个不同的值:true、false 和 null public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { bool? nb = (bool?)value; switch (nb) { case true: return State.Available; case false: return State.Locked; case null: default: return State.Unknown; } } }
下面我们如何在XAML里消费这些Converter呢?
<Window x:Class="Chapter6.Page124.ConverterDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Chapter6.Page124.ConverterDemo" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <local:CategoryToSourceConverter x:Key="cts"/> <local:StateToNullableBoolConverter x:Key="stnb"/> </Window.Resources> <StackPanel> <ListBox x:Name="listBoxPlane" Height="160" Margin="5"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image Width="20" Height="20" Source="{Binding Path=Category,Converter={StaticResource cts}}"/> <TextBlock Text="{Binding Path=Name}" Width="60" Margin="80,0"/> <CheckBox IsThreeState="True" IsChecked="{Binding Path=State,Converter={StaticResource stnb}}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Button x:Name="buttonLoad" Content="Load" Height="25" Margin="5,0" Click="buttonLoad_Click"/> <Button x:Name="buttonSave" Content="Save" Height="25" Margin="5,5" Click="buttonSave_Click"/> </StackPanel></Window>XAML代码中已经添加了对程序集的引用并映射为名称为Local,同时,以资源的形式创建了两个Converter实例。名为listBoxPlane和ListBox控件是我们的重点,需要为他们添加用于显示数据的DataTemplate。
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void buttonLoad_Click(object sender, RoutedEventArgs e) { List<Plane> planList = new List<Plane>() { new Plane(){ Category=Category.Bomber, Name="B-1",State=State.Unknown}, new Plane(){ Category=Category.Bomber, Name="B-2",State=State.Unknown}, new Plane(){ Category=Category.Fighter, Name="F-22",State=State.Unknown}, }; this.listBoxPlane.ItemsSource = planList; } private void buttonSave_Click(object sender, RoutedEventArgs e) { StringBuilder sb = new StringBuilder(); foreach (Plane p in listBoxPlane.Items) { sb.AppendLine(string.Format("Category={0}, Name={1}, State={2}", p.Category, p.Name, p.State)); } File.WriteAllText(@"D:\PlaneList.txt", sb.ToString()); } }
- Binding的数据转换
- WPF中的binding(十一)- Binding数据的转换
- Binding的数据转换(Data Converter)
- Binding之数据转换
- Binding- 数据转换
- 数据绑定(十)Binding的数据转换
- WPF Data Binding之数据的转换和校验【四】
- WPF应用Binding之数据转换
- Binding对数据的校验
- binding 数据 model的写法
- WPF中的binding(十)- Binding数据的校验
- WPF使用Binding对数据的校验
- 数据绑定库Data Binding的使用
- 数据绑定(九)Binding的数据校验
- Binding(五)——使用XML数据作为Binding的源
- WPF中的binding(六)- 使用XML数据作为Binding的源
- Silverlight 数据绑定(Binding)
- Silverlight 数据绑定(Binding)
- 一句话
- ecos linker script
- No result defined for action ** and result input 解决
- 走近SSH之Hibernate--Hibernate环境搭建(MyEclipse+MySql)
- PPP Generic Driver and Channel Interface
- Binding的数据转换
- Linux shell中的函数调用实践
- In App Purchase 例子PurchaseTest 解决 "status":21002
- cocos2d-x 3.0创建新项目
- 永成科技C++笔试题
- 【ARM学习笔记】五、操作系统Operation System和内存管理单元MMU
- ASP.NET三层架构介绍及数据库配置方法
- 自己修改的Ajax注册和登录验证
- Win7系统中bat 后缀文件关联程序恢复