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. 【Mood-6】空气显示触摸屏、智能钱夹

    空气显示触摸屏 这款屏幕借助从设备中送出的空气和水在空中形成投影,可以用来展示计算机或平板中的图像.此外,它还可以实现人机互动.你只需在虚拟屏幕前挥动双手,就能完成一系列的隔空操作,如滑动.捏合.缩放 ...

  2. Androidstudio 点9图报错的问题

    在eclipse上.9图能够正常使用,但是到了Androidstudio上就报错无法引用,提示找不到.9图的问题.   解决方案: Androidstudio对.9图进行了更严格的定义, 1. 如果一 ...

  3. TaskUtil多线程与定时任务

    package com.taoban.util; /**  * 执行单次任务或定时任务工具类(用于减少new Thread()和new Timer()的使用)  */ public class Tas ...

  4. codeforces 678D D. Iterated Linear Function(水题)

    题目链接: D. Iterated Linear Function time limit per test 1 second memory limit per test 256 megabytes i ...

  5. POJ 2516 Minimum Cost 最小费用流

    题目: 给出n*kk的矩阵,格子a[i][k]表示第i个客户需要第k种货物a[i][k]单位. 给出m*kk的矩阵,格子b[j][k]表示第j个供应商可以提供第k种货物b[j][k]单位. 再给出k个 ...

  6. ASP.Net 验证控件 RegularExpressionValidator

    定义和用法 RegularExpressionValidator 控件用于验证输入值是否匹配指定的模式. 注释:除非浏览器不支持客户端验证或 EnableClientScript 属性被设置为 fal ...

  7. sqlserver跟踪

    本文以实际应用为目的,不在理论方面深究 1.打开跟踪器 或 2.新建跟踪-事件选择-列筛选器,HostName默认不显示,需勾选“显示所有列”,如果希望只跟踪某一客户端,可按下面的设置HostName ...

  8. 代码研磨 Slim v3 (二)--app->run()

    APP->run()代码如下:   /** * Run application * * This method traverses the application middleware stac ...

  9. c#中文件上传(1)

    * * ;//3M picPath = Server.MapPath("........."); HttpFileCollection postfile = Context.Req ...

  10. LINQ to SQL 语句(3) 之 Count/Sum/Min/Max/Avg

    LINQ  to SQL 语句(3) 之  Count/Sum/Min/Max/Avg [1] Count/Sum 讲解 [2] Min 讲解 [3] Max 讲解 [4] Average 和 Agg ...