Silverlight数据绑定中的可空类型与自定义转换器

在Silverlight中,可以通过绑定对绑定目标属性和数据源进行连接。如:

XAML代码:

< UserControl x:Class ="ValidatorDemo.BindingSample"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
Width
="400" Height ="300" >
< StackPanel x:Name ="LayoutRoot" Width ="200" >
< TextBox Text =" {Binding Name, Mode=TwoWay} " Margin ="10"   ></ TextBox >
< TextBox Text =" {Binding Age, Mode=TwoWay} " Margin ="10" ></ TextBox >
< Button Content ="Show" Click ="Show" Margin ="10" ></ Button >
</ StackPanel >
</ UserControl >

C#代码:

public   partial   class BindingSample : UserControl
{
   
public BindingSample()
    {
        InitializeComponent();

       
this .LayoutRoot.DataContext =   this .people;
    }

   
private People people =   new People();

   
private   void Show( object sender, RoutedEventArgs e)
    {
        MessageBox.Show(
string .Format( " {0} is {1}. " , this .people.Name, this .people.Age));
    }
}

public   class People
{
   
public   string Name { get ; set ; }
   
public   int ? Age { get ; set ; }
}

运行程序,效果如下图:

image 

这时,如果清空第二个文本框(显示年龄)中的值,然后点击“Show”按钮,问题出现了:数据源中的属性(此处为People中的Age属性)值并没有改为null,而是修改之前的8。

如果将绑定的ValidatesOnExceptions属性赋值为True,可以看到更清晰的效果:

 image

第二个文本框上打上了清晰的标志,告诉我们输入格式不正确。这表明绑定引擎捕捉到了绑定目标更新源对象时发生的异常,进一步可以理解为,默认的转换器不能处理将空字符串到int?类型的转换。为了解决这个问题,我们可以自定义如下转换器:

public   class IntConverter : IValueConverter 

   
public   object Convert( object value, Type targetType, object parameter, CultureInfo culture) 
    { 
       
return value ==   null   ?   null : value.ToString(); 
    }
   
public   object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture) 
    { 
       
string str = value as   string
       
if ( string .IsNullOrEmpty(str)) return   null ;
        str = str.Trim(); 
       
if (str.Length ==   0 ) return   null
       
int v; 
       
bool isvalid =   int .TryParse(str, out v); 
       
if ( ! isvalid) return   null ;
       
return v; 
    } 
}

使用自定义转器的XAML代码如下:

< UserControl x:Class ="ValidatorDemo.BindingSample"  
    xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"  
    xmlns:local ="clr-namespace:ValidatorDemo"  
    Width ="400" Height ="300" >  
   
< StackPanel x:Name ="LayoutRoot" Width ="200" >  
       
< StackPanel.Resources >  
           
< local:IntConverter x:Key ="IntConverter" ></ local:IntConverter >  
       
</ StackPanel.Resources >  
       
< TextBox Text =" {Binding Name, Mode=TwoWay, ValidatesOnExceptions=True} " Margin ="10"   ></ TextBox >  
       
< TextBox Text =" {Binding Age, Mode=TwoWay, ValidatesOnExceptions=True, Converter={StaticResource IntConverter}} "  
            Margin ="10" ></ TextBox >  
       
< Button Content ="Show" Click ="Show" Margin ="10" ></ Button >  
   
</ StackPanel >  
</ UserControl >

 至此,从空字符串到int?型空值转换的问题解决了。但自定义转换器中如下两行代码依然存在问题:

bool isvalid =   int .TryParse(str, out v); 
if ( ! isvalid) return   null ;

从字符串到int?类型转换时,如果字符串不是合法的数字字符串,则转换不会成功,如果返回null,转换器不抛出异常,绑定引擎当然也无法捕捉转换过程发生的异常。而如果转换过程中抛出异常,同样不幸的是:

 

数据绑定引擎不捕获由用户提供的转换器所引发的异常。由 ConvertBack 方法引发的任何异常,或由 ConvertBack 方法调用的方法所引发的任何未捕获的异常,均视为运行时错误。通过返回 DependencyProperty.UnsetValue 处理预期的问题。(MSDN原文)

 

该如何完美解决呢?希望高手指点。

转载于:https://www.cnblogs.com/chinadhf/archive/2010/03/30/1700698.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值