Binding在Slider控件与TextBox控件之间建立关联,值可以互相绑定,但是它们的数据类型是不同的,Slider是Double类型,Text为String。原来,Binding有一种机制称为数据转换(Data Converter),当数据绑定的源与目标不同类型时,处理比较简单时,系统就自动的进行了类型转换,但是对于相对复杂的类型转换时,就需要我们手动进行了。

下面用一个例子来说明Convert的应用,程序的用途是在列表里面向玩家显示一些球的状态。

首先创建几个自定义数据类型:

public enum Category
{
Basketball,
football
}
public enum State
{
Available,
Locked,
Unknown
}
public class ball
{
public Categroy Categroy { get;set; }
public string Name { get; set; }
public State State { get; set; }
}

程序后面要用到的图片已经加载到程序中,球的State属性在UI里被映射为CheckBox。因为存在两个映射关系,我们需要提供两个Convert:一个是由Category类型单向转换为string,另一个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.Basketball:
return @"basketball.png";
case Category.football:
return @"football.png";
default:
return null;
}
}
//不会被调用
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class StateToNullableBoolConvert : IValueConverter
{
//将state转换为bool?
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
State s = (State)value;
switch (s)
{
case State.Locked:
return false;
case State.Available:
return true;
case State.Unknown:
default:
return null;
}
}
//将bool?转换为State
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。XAML代码的框架如下:

<Window x:Class="DataConverter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataConverter"
Title="MainWindow" Height="350" Width="525"> <Window.Resources>
<local:CategoryToSourceConverter x:Key="cts"/>
<local:StateToNullableBoolConvert x:Key="stnb"/>
</Window.Resources>
<Grid>
<StackPanel Background="LightBlue">
<ListBox x:Name="listBoxPlan" Height="160" Margin="5,0"></ListBox>
<Button x:Name="buttonLoad" Content="Load" Height="25" Margin="5,0"></Button>
<Button x:Name="buttonSave" Content="Save" Height="25" Margin="5,5"></Button>
</StackPanel>
</Grid>
</Window>

XAML代码中已经添加了对程序集的引用并映射为名称空间local,以资源的形式创建了两个Convert的实例。名为ListBoxPlan的ListBox控件需要为它添加用于显示数据的DataTemplate。我们把焦点集中在ListBox控件的ItemTemplate属性上:

<ListBox x:Name="listBoxPlan" Height="160" Margin="5,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Width="20" Height="20"
Source="{Binding Path=Category,Converter={StaticResource cts}}"></Image>
<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>

Load按钮的Click事件处理负责把一组球的数据赋值给ListBox的ItemSource属性,Save按钮的Click事件处理器负责把用户更改过的数据写入文件:

//Load按钮Click事件处理器
private void buttonLoad_Click(object sender, RoutedEventArgs e)
{
List<Ball> ballList = new List<Ball>()
{
new Ball(){Category = Category.Basketball,Name = "NBA",State = State.Unknown},
new Ball(){Category = Category.Basketball,Name = "CBA",State = State.Unknown},
new Ball(){Category = Category.football,Name = "世界杯",State = State.Unknown},
new Ball(){Category = Category.football,Name = "欧冠",State = State.Unknown},
new Ball(){Category = Category.Basketball,Name = "WNBA",State = State.Unknown},
new Ball(){Category = Category.football,Name = "英超",State = State.Unknown}
};
this.listBoxPlan.ItemsSource = ballList;
}
//Save按钮Click事件处理器
private void buttonSave_Click(object sender, RoutedEventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach (Ball b in listBoxPlan.Items)
{
sb.AppendLine(string.Format("Category={0},Name={1},State={2}", b.Category, b.Name, b.State));
}
File.WriteAllText(@"D:\BallList.txt", sb.ToString());
}

运行程序并单击CheckBox更改State,效果图如下:

单击Save按钮后打开D:\BallList.txt:

注*读《深入浅出WPF》读书笔记

WPF之Binding对数据的转换(第五天)的更多相关文章

  1. WPF 基础 - Binding 对数据的转换和校验

    1. Binding 对数据的转换和校验 Binding 中,有检验和转换关卡. 1.1 数据校验 源码: namespace System.Windows.Data { public class B ...

  2. WPF 之 Binding 对数据的校验与转换(三)

    一.前言 ​ Binding 的作用就是架在 Source 和 Target 之间的桥梁,数据可以在这座桥梁的帮助下来流通.就像现实中的桥梁会设置一些关卡进行安检一样,Binding 这座桥上也可以设 ...

  3. WPF之Binding深入探讨

    原文:http://blog.csdn.net/fwj380891124/article/details/8107646 1,Data Binding在WPF中的地位 程序的本质是数据+算法.数据会在 ...

  4. WPF的Binding功能解析

    1,Data Binding在WPF中的地位 程序的本质是数据+算法.数据会在存储.逻辑和界面三层之间流通,所以站在数据的角度上来看,这三层都很重要.但算法在3层中的分布是不均匀的,对于一个3层结构的 ...

  5. WPF之Binding深入探讨--Darren

    1,Data Binding在WPF中的地位 程序的本质是数据+算法.数据会在存储.逻辑和界面三层之间流通,所以站在数据的角度上来看,这三层都很重要.但算法在3层中的分布是不均匀的,对于一个3层结构的 ...

  6. WPF之Binding【转】

    WPF之Binding[转] 看到WPF如此之炫,也想用用,可是一点也不会呀. 从需求谈起吧: 首先可能要做一个很炫的界面.见MaterialDesignInXAMLToolKit. 那,最主要的呢, ...

  7. WPF之Binding深入探讨 转载:http://blog.csdn.net/fwj380891124/article/details/8107646

    1,Data Binding在WPF中的地位 程序的本质是数据+算法.数据会在存储.逻辑和界面三层之间流通,所以站在数据的角度上来看,这三层都很重要.但算法在3层中的分布是不均匀的,对于一个3层结构的 ...

  8. WPF备忘录(3)如何从 Datagrid 中获得单元格的内容与 使用值转换器进行绑定数据的转换IValueConverter

    一.如何从 Datagrid 中获得单元格的内容 DataGrid 属于一种 ItemsControl, 因此,它有 Items 属性并且用ItemContainer 封装它的 items. 但是,W ...

  9. [转]深入浅出WPF(7)——数据的绿色通道,Binding

    本文转自:http://liutiemeng.blog.51cto.com/120361/95273 小序: 怎么直接从2蹦到7啦?!啊哦,实在是不好意思,最近实在是太忙了,忙的原因也非常简单——自己 ...

随机推荐

  1. 【开源项目10】安卓图表引擎AChartEngine

    安卓图表引擎AChartEngine(一) - 简介 http://blog.csdn.net/lk_blog/article/details/7645509 安卓图表引擎AChartEngine(二 ...

  2. android开发之路12(android四大组件&Fragment&AsyncTask类)

    一.Activity组件1.简介:Activity组件是Android四大组件之一,通常一个Activity相当于一个用户界面,我们可以通过加载布局文件将Android提供的各种控件及自定义控件显示到 ...

  3. Hessian矩阵

    http://baike.baidu.com/link?url=o1ts6Eirjn5mHQCZUHGykiI8tDIdtHHOe6IDXagtcvF9ncOfdDOzT8tmFj41_DEsiUCr ...

  4. Oracle数据库作业-1

    设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的表(一)~表(四)所示,数据如表1-2的表 ...

  5. CSS3--幽灵按钮特效(实例)

    先预览效果 其中用到了CSS3的Transition属性:设置动画时间.效果:Transform属性:设置元素旋转.位移:box-sizing属性:以特定的方式定义某个区域的特定元素: 制作小三角方法 ...

  6. ASP.NET缓存全解析5:文件缓存依赖 转自网络原文作者李天平

    这种策略让缓存依赖于一个指定的文件,通过改变文件的更新日期来清除缓存. ///<summary> /// 获取当前应用程序指定CacheKey的Cache对象值 ///</summa ...

  7. Part 10 AngularJS sort rows by table header

    Here is what we want to do 1. The data should be sorted when the table column header is clicked 2. T ...

  8. MVC小例子

    [约定胜于配置] 1. 右键Mode数据层添加新建项,用linq连接数据库 (不要在控制层上直接操控linq,要在数据层新建一个类,来对数据库进行操作) 2. 右键Mode数据层添加类,来完成对数据库 ...

  9. Cocos2d-JS特效

    Cocos2d-JS提供了很多特效,这些特效事实上属于间隔动作,特效类cc.GridAction类,也称为网格动作,它的类图如下图所示. 网格动作类图 网格动作cc.GridAction它有两个主要的 ...

  10. (转)MongoDB 3.0 WT引擎参考配置文件

    mongodb 3.0 改变很多,从2.6版本升级到3.0要关注的细节很多,如权限等等.3.0在数据存储引擎上更换成了wiredTiger,在数据压缩方面很有效,解决大数据量问题的情况下,磁盘不够用的 ...