zoukankan      html  css  js  c++  java
  • Silverlight3系列(七)数据绑定 Data Binding 3 数据类型转换 Data Converter Virus

     Silverlight3系列(七)数据绑定 Data Binding 3 数据类型转换 Data Converter

    7 数据转换

      在普通的情况下,数据从后台到前台显示,没有任何变化。看起来是符合逻辑的,但是有可能不是你想要的效果,数据源的数据可能是的低级别的(这里的低级别是说数据比较原始,或者说是数据库可以理解的,不是最终用户可以理解的形式),你不想让他直接显示在界面上。例如:你可能会将数字变成用户可以看懂的形式、或者是想让日期显示成长格式的字符串。如果是这样的话,你需要将数据转换成正确的显示形式。如果是双向绑定,你也需要将用户提供的数据转换成数据库可以存储的形式。

      很幸运的是,Silverlight允许你创建一个值转换类来完成。这个值转换类负责将数据库的值转换成可以显示的值,如果是双向绑定,还可以将用户输入的值转换成数据库可以存储的值。

      在数据绑定中,值转换是很常用的。你可以在下列的情况中使用它们:

      1)将数据格式化成string。例如:将数字转换成string,这是最常用的方式,但不是唯一的功能。

      2)创建一个特殊的Silverlight类型。例如:你将读取的一些二进制数据创建成一个BitmapImage对象,以便可以将它绑定到一个Image控件。

      3)有条件的改变一个绑定数据的一些属性。例如:通过值转换类改变一个控件的背景色,或者是高亮显示其中的一部分。

      

      7.1 使用值转换格式换字符串

      值转换对于需要从数字显示为字符串的时候,是一个很好的工具。例如:你的一个商品的单价属性,在数据库中你可能使用decimal存储,但是显示的时候你需要显示为3.9900,或者你还需要显示成一个钱的符号,就好像¥49.99

      你可以通过下面的步骤创建一个值转换类。

      1)创建一个实现IValueConverter接口(接口在System.Windows.Data空间下面)的类,将这个类放在你的Silverlight项目中,而不是webservice项目中。

      2)实现Convert()方法,将原始值转换为可以显示的值。

      3)实现ConvertBack()方法,反过来,将显示的值,转换为原始的值。

      

      上图是一个转换的示意图。

      在decima数值lcurrency货币的转换中,你可以使用Decimal.ToString()方法来完成,你需要设置转换结果的形式“C”

      string currentyText=decimalPrice.ToString("C");

      方法中的环境设置使用了当前的运行环境语言文件,如果简体中文是当前的语言环境的话,就会显示¥符号。如果你想换成另外一个语言显示形式,你就需要声明语言环境,例如你想显示美元形式,你需要这么做

      CultureInfo culture=new CultureInfo"en-US";

      string currentyText=decimalPrice.ToString("C",culture);

      下面是几种常用的字符串格式形式。

                        

     Type 

    FormatString

    Example

    Currency

    C

    $1,234.50

    Scientific

    科学计数法

    E

    1234.50E+004

    Percentage

    P

    45.6%

    Fixed Decimal

    F?

     小数点后的几位,F3会格式为123.400F0会格式为123

    Short Date

    d

    M/d/yyyy

    For example:10/30/2009

    Long Date

    D

    dddd,MMMM dd,yyyy

    For example:Monday,January 30,2005

    Long Date and Short Time

    f

    dddd,MMMM dd,yyyy HH:mm aa

    For example:Monday,January 30,2005 10:00 AM

     

    Long Date and Long Time

    F

    ddd,MMMM dd,yyyy HH:mm:ss aa

    For example:Monday,January 30,2005 10:00:26 AM

    ISO Sortable Standard

    s

    yyyy-MM-dd HH:mm:ss

    For example:2005-01-30 10:02:18

    Month and Day

    M

    MMMM dd

    For example:January 30

    General

    G

    M/d/yyyy HH:mm:ss aa(依赖于本地设置)

    For example:10/30/2005 10:00:23 AM

       

          从显示格式转换成数值,可能需要一点小技巧。double类型的Parse()和TryParse()方法是一种选择,但是通常他们不能处理带有货币符号的字符串。解决的办法是,使用重载的ParseTryParse方法,在方法中添加一个System.Globalization.NumberStyles值。如果你使用System.Globalization.NumberStyles.Any,你可以成功的去除货币符号,如果它存在。

          下面是一个价格转换的例子。

         

     

    代码

    public class PriceConverter:IValueConverter 
        {

            
    #region IValueConverter Members

            
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                
    double price = (double)value;
                
    return price.ToString("C", culture);
            }

            
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                
    string price = value.ToString();
                
    double result;

                
    if (double.TryParse(price, System.Globalization.NumberStyles.Any, culture, out result) == true)
                {
                    
    return result;
                }
                
    return value;
            }

            
    #endregion

          如果要使用这个转换,你需要在声明一个命名空间,下面假定你的值转换类处于Silverlight.ValueConverter命名空间下面。

          xmlns:local="clr-namespace:Silverlight.ValueConverter"

      你需要将上面的这个属性添加到顶级节点<UserControl>中,现在你需要在页面的资源集合中创建一个PriceConverter类,

      <Usercontrol.Resources>

        <local:PriceConverter x:Key="PriceConverter" ></local:PriceConverter>

      </Usercontrol.Resources>

      然后你可以绑定一个静态资源

        <TextBox Margin="5" Grid.Row="0" Grid.Column="0"
               Text="{Binding UnitCost, Mode=TwoWay, Converter={StaticResource PriceConverter}}"></TextBox>

      7.2 使用值转换创建对象

      值转换独立于数据的存储方式和数据的展示方式。例如:你有一个图片以二进制的形式存储在数据库中,你可以把它转换成System.Windows.Media.Imaging.BitmapImage对象。当然了,这么设计也许不是最合适的。

      你可能需要很灵活的创建更多的类型,你的数据类库可能被Silverlight和Windows Form(需要转换成System.Drawing.Bitmap)都有调用。在这种情况下,你需要将原始的二进制转换成BitmapImage类型。

      从二进制转换为一张图片,你首先要创建一个BitmapImage对象,同时将二进制读到MemoryStram中。然后,调用BitmapImage.SetSource()方法,将流中的数据传输给BitmapImage对象。

      产品表中的可能没有存储二进制的图片信息,可能存储的是和产品有关的图片的路径。这种情况下,你就更有理由延缓创建图片对象。第一,图片可能没有访问权限,依赖于应用运行在哪里;第二,没有必要分配额外的内存资源,除非你要显示它。

      ProductImage字段存储的是图片的文件名,不是图片的完整路径。这样给你一个灵活的配置,你可以从任何地方获取图片。值转换环类有任务将存储的文件名结合网站,返回图片的地址。网站的根URI使用一个自定义属性RootUri存储,默认是网站的Uri,下面是完整代码。

      

    代码
        public partial  class ImagePathConverter:IValueConverter 
        {
            
    private string _rootUri;
            
    public string RootUri
            {
                
    get { return this._rootUri; }
                
    set { this._rootUri = value; }
            }
            
    public ImagePathConverter()
            {
                
    string uri = "http://baidu.com/";
                _rootUri 
    = uri.Remove(uri.LastIndexOf("/"),
                uri.Length 
    - uri.LastIndexOf('/'));
            }
            
    #region IValueConverter Members

            
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                
    string imagePath = RootUri + "/" + (string)value;
                
    return new System.Windows.Media.Imaging.BitmapImage(new Uri(imagePath));
            }

            
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                
    //图片是不能编辑的,这里就没有必要支持反向转换
                throw new NotImplementedException();
            }

            
    #endregion
        }

     

    代码
    <UserControl x:Class="Silverlight.ValueConverter.ImagePathConverterPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namaspace:Silverlight.ValueConverter"
        Width="400" Height="300">
        <UserControl.Resources >
            <local:ImagePathConverter x:Key="ImagePathConverter"></local:ImagePathConverter>
        </UserControl.Resources>
            <Grid x:Name="LayoutRoot" Background="White">
                <Grid.ColumnDefinitions >
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions >
                    <RowDefinition></RowDefinition>
                    <RowDefinition></RowDefinition>
                </Grid.RowDefinitions>
                <Image Margin="5" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left"
                Source="{Binding ProductImagePath, Mode=TwoWay, Converter={StaticResource ImagePathConverter}}"></Image>
            </Grid>
    </UserControl>

      你可以改进这里例子,首先,在创建一个不存在图片的BitmapImage的时候你可以抛异常,在你绑定数据的时候可以收到。或者你可以在ImagePathConverter类中加一个属性,来配置这个行为。添加一个bool类型的属性SuppressExceptions。如果设置为true,你可以捕获一个异常,然后再Convert方法中返回一个空字符串,或者添加一个默认的图片,如果有异常就显示这个默认的图片。

      7.3 应用有条件的格式化

      有一些很有意思的转换在表现层中设计不到。相反,你打算使用一些数据规则来控制显示效果。

      例如:你想要根据值的大小变化背景颜色,你就可以声明下面这样一个类

      

    代码
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Data;

    namespace Silverlight.ValueConverter
    {
        
    public class PriceToBackgroundConverter:IValueConverter 
        {
            
    public double MinimumPriceToHighlight
            { 
    setget; }
            
    public Brush HighlightBrush
            { 
    setget; }
            
    public Brush DefaultBrush { setget; }


            
    #region IValueConverter Members

            
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                
    double price = (double)value;

                
    if (price >= MinimumPriceToHighlight)
                    
    return HighlightBrush;
                
    else
                    
    return DefaultBrush;
            }

            
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                
    throw new NotImplementedException();
            }

            
    #endregion
        }
    }
    代码
    <UserControl x:Class="Silverlight.ValueConverter.ImagePathConverterPage"
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml" 
                   xmlns:loc
    ="clr-namespace:Silverlight.ValueConverter"
        Width
    ="400" Height="300">
        
    <UserControl.Resources >
                  
    <loc:PriceToBackgroundConverter x:Key="PriceToBackgroundConverter"
                                              DefaultBrush
    ="{x:null}" HighlightBrush="Orange" MinimumPriceToHighlight="50"></loc:PriceToBackgroundConverter>
        
    </UserControl.Resources>
            
    <Grid x:Name="LayoutRoot" Background="White">
                
    <Grid.ColumnDefinitions >
                    
    <ColumnDefinition></ColumnDefinition>
                    
    <ColumnDefinition></ColumnDefinition>
                
    </Grid.ColumnDefinitions>
                
    <Grid.RowDefinitions >
                    
    <RowDefinition></RowDefinition>
                    
    <RowDefinition></RowDefinition>
                
    </Grid.RowDefinitions>
            
    <Border Background="{Binding UnitCost, Converter={StaticResource PriceToBackgroundConverter}}" ></Border>
            
    </Grid>
    </UserControl>

      

     <Border Background="{Binding UnitCost, Converter={StaticResource PriceToBackgroundConverter}, ConverterParameter=50}" ></Border>

      如果想上面这样传递了ConverterParameter参数的话,可以在Convert方法中使用

      

     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                double price = (double)value;

                if (price >= double.Parse (parameter .ToString ()))
                    return HighlightBrush;
                else
                    return DefaultBrush;
            }

      

      

  • 相关阅读:
    NoSQL数据库:Java开源项目Neo4j简介
    EPOLL和IOCP比较
    CString&CStringA&CStringW之间的相互转换
    CString和CStringA之间的转换
    Windows IOCP模型与Linux EPOLL模块之比较
    OCP-1Z0-053-V13.02-708题
    OCP-1Z0-053-V13.02-709题
    OCP-1Z0-053-V12.02-342题
    OCP-1Z0-053-V12.02-341题
    OCP-1Z0-053-V13.02-706题
  • 原文地址:https://www.cnblogs.com/virusswb/p/1659117.html
Copyright © 2011-2022 走看看