Silverlight陷阱:XAML中不能使用自定义字典

我们知道,XAML中实际上是可以放置任何对象的,而系统将按照如下的规则管理嵌套的内容:

1. 如果对象实现了IList,那么嵌套内容将通过IList.Add添加到父对象;

2. 如果对象实现了IDictionary,并且元素用x:Key指定了键值,那么嵌套内容将通过IDictionary.Add添加到父对象;

3. 如果只有父对象用ContentPropertyAttribute声明了内容属性,那么嵌套内容将被赋值为到该属性。

 

我们在目前的项目中使用了很多XAML声明来减少编码量,但是在使用中我们发现,第2条对于Silverlight是不适用的,Silverlight的XAML只支持对Resources属性用字典方式来声明,对于自定义的字典内容,即使是ResourceDictionary也无法读取,否则运行时就会抛出异常。因为同样的方法在服务端已经普遍使用,所以我们把代码应用到Silverlight工程中的时候,根本没有想到这方面会出问题。从而花了很长时间、走了很多弯路去查找自己程序中的Bug,反复作了大量实验后,终于确定:这个问题来源于Silverlight和WPF读取XAML时的表现不同。

 

还是用代码来说明。首先我们看看在WPF中使用自定义字典是否可行:

 

public   class  BaseWindow : Window
{
    
public  BaseWindow()
    {
        Dict 
=   new  MyDict();
    }

    
public  MyDict Dict {  get set ; }
}

public   class  MyDict : Dictionary < string , Brush >
{
}

 然后在窗体中添加字典数据:

 

< local:BaseWindow  x:Class ="TestWPF2.Window1"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
    Title
="Window1"  
    xmlns:local
="clr-namespace:TestWPF2" >

    
< local:BaseWindow.Dict >
            
< SolidColorBrush  x:Key ="1"  Color ="Blue"   />
            
< SolidColorBrush  x:Key ="2"  Color ="Black"   />
    
</ local:BaseWindow.Dict >
</ local:BaseWindow >

 最后检查一下声明的字典是否正确设置了:

 

public  Window1()
{
    InitializeComponent();
    
this .Background  =  Dict[ " 1 " ];
}

运行结果完全正确(如图) ,表明自定义字典在WPF中是可行的。

 

 

然后我们再如法炮制一个Silverlight工程,运行之,出现异常:


 AG_E_PARSER_BAD_PROPERTY_VALUE [Line: 10 Position: 42]Type: XamlParseExceptionStackTrace:   

位于 System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)  

位于 TestSL2.MainPage.InitializeComponent()  

位于 TestSL2.MainPage..ctor()  

位于 TestSL2.App.App_Startup(Object sender, StartupEventArgs e)  

位于 System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)  

位于 MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)

 

此实验可以说明WPF和Silverlight 在处理XAML时候的不同行为。你可以把MyDict换成ResourceDictionary试试,结果也是一样的。

 

为了绕过这个问题,我们不得不在Silverlight工程中去掉字典,把内容重新组织成列表,然后在程序中将内容重新组织成字典——等于服务端已经调试好的方法在客户端又重写了一遍。非常恼人,但是没有办法。。

 

这个问题告诉我们,尽管Silverlight 源出WPF,但处理细节上还是存在微妙的差别。将WPF的经验应用到Silverlight上,不见得会奏效。最好是先作一些小实验,确信方法是可行的,再添加到工程里,否则在大的项目里调试此类问题(尤其是XAML这类既缺乏编译器检查,又没有调用堆栈可查的东西)真够杀死你几万个脑细胞的。

转载于:https://www.cnblogs.com/shuhari/archive/2009/11/12/silverlight_issue_dictionary.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值