Silverlight自定义控件管理二重奏

开发 后端
用Silverlight创建自定义控件,最原始的办法就是把所有样式都直接写在generic.xaml文件里,但如果自定义控件足够多,generic.xaml 达到了好几千行,管理起来当然十分麻烦,这里给大家介绍两种较为方便的管理方法。

Silverlight里面建自定义控件(Templated Control),会在工程下生成一个Themes文件夹,并在其中包含一个generic.xaml文件。这是一个ResourceDictionary文件,所有的自定义控件的默认样式(Default Style)都必须放在这里。

最原始的办法就是把所有样式都直接写在generic.xaml文件里,但如果自定义控件足够多,generic.xaml 达到了好几千行,管理起来当然十分麻烦。后来在同事的推荐下,得到两种方法可以将各自定义控件的样式分开管理,总算解决了这一令人头疼的问题。

MergeDefaultStyle方法

如果研究过Silverlight Toolkit的源代码,会发现里面所有的自定义控件都有一个单独的xaml文件来保存控件的默认样式,当然这些文件是不起作用的。最初以为是先用单独的xaml文件来写控件样式,然后再拷贝到generic.xaml里,也就是人工同步。

然而现在发现MergeDefaultStyle方法。MergeDefaultStyle就是通过给所有单独的xaml文件应用一种特殊的 Build 方法,在 Build 工程的时候,自动把 xaml 文件的内容整合到 generic.xaml 里去。

重点步骤是:

1. 拷贝里面的代码或者直接下载MergeDefaultStyle.dll。

2. 在VS里面Unload你的工程,然后编辑工程文件,或者直接用文本编辑器打开csproj文件。

3. 在最后加上下面这段代码:

  1. <UsingTask 
  2.   TaskName="Engineering.Build.Tasks.MergeDefaultStylesTask" 
  3.   AssemblyFile="$(EngineeringResources)\Engineering.Build.dll" /> 

注意:AssemblyFile 的值是你放MergeDefaultStyle.dll的位置,可以用相对路径。

4. 再在后面加上这一段代码:

  1. <!-- Add "DefaultStyle" as a Build Action in Visual Studio --> 
  2. <ItemGroup Condition="'$(BuildingInsideVisualStudio)'=='true'"> 
  3.   <AvailableItemName Include="DefaultStyle" /> 
  4. </ItemGroup> 
  5. <!--  
  6. Merge the default styles of controls 
  7. (only if any of the DefaultStyle files is  
  8. more recent than the project's generic.xaml file)
  9. before compilation  
  10. dependencies are processed.  
  11. --> 
  12. <PropertyGroup> 
  13.   <PrepareResourcesDependsOn> 
  14.     MergeDefaultStyles;  
  15.     $(PrepareResourcesDependsOn);  
  16.   </PrepareResourcesDependsOn> 
  17. </PropertyGroup> 
  18. <Target 
  19.   Name="MergeDefaultStyles" 
  20.   Inputs="@(DefaultStyle)" 
  21.   Outputs="$(MSBuildProjectDirectory)\generic.xaml"> 
  22.   <MergeDefaultStylesTask 
  23.     DefaultStyles="@(DefaultStyle)" 
  24.     ProjectDirectory="$(MSBuildProjectDirectory)" /> 
  25. </Target> 
  26. <!--  
  27. Touch DefaultStyles on Rebuild to force generation of generic.xaml.  
  28. --> 
  29. <PropertyGroup> 
  30.   <RebuildDependsOn> 
  31.     TouchDefaultStyles;  
  32.     $(RebuildDependsOn);  
  33.   </RebuildDependsOn> 
  34. </PropertyGroup> 
  35. <Target Name="TouchDefaultStyles"> 
  36.   <Touch Files="@(DefaultStyle)" ForceTouch="true" /> 
  37. </Target> 

5. 重新 Load 你的工程。

6. 选择有默认样式的单独的xaml,在属性窗口的 Build Action 里面选择 DefaultStyle 。

7. 编译整个工程,再打开generic.xaml文件,你会发现 xaml 文件里的内容已经拷到generic.xaml里面了。

这一方法适用于Silverlight 3及Silverlight 4 。

MergedDictionary方法

上面的方法可谓是一劳永逸了,但多少有点不官方。而且其实还是generic.xaml掌控全局,一旦一个xaml文件出了纰漏,会影响所有的控件跟着出错。这样排查起来也麻烦的很。

于是在Silverlight 3里就出来了一个更简单更官方的方法。如前所述,generic.xaml文件包含了一个ResourceDictionary,而Silverlight 3里面的ResourceDictionary 多了一个MergedDictionaries的属性,可以把其他ResourceDictionary通过资源路径整合到一个ResourceDicionary里面。

其实新建一个Silverlight导航应用时,就可以在App.xaml 里面看到这一属性的应用。需要注意的是,在 App.xaml 里面是可以用相对路径的,而在 generic.xaml 里面,不可以用相对路径,而应当用 "/AssemblyName;component/path”的方法说明文件路径。

比如你的工程的AssemblyName是Slippor.Controls,而xaml的路径是CustomControl文件夹下的CustomControl.xaml 。则应该在generic.xaml里面如下写:

  1. <ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> 
  3.   <ResourceDictionary.MergedDictionaries> 
  4.     <ResourceDictionary Source="/Slippor.Controls;component/CustomControl/CustomControl.xaml"/> 
  5.   </ResourceDictionary.MergedDictionaries> 

</ResourceDictionary>这一方法适用于Silverlight 3及Silverlight 4。

原文作者:smjack

原文地址:http://www.cnblogs.com/smjack/archive/2010/08/24/1807706.html

【编辑推荐】

  1. 全屏模式下处理Silverlight控件的两种方式
  2. 细数Silverlight 4的十二大引人注目新特性
  3. Silverlight 4中XAML解析的变化
责任编辑:王晓东 来源: 博客园
相关推荐

2020-03-03 13:53:10

AI金融IOT

2013-04-19 10:14:24

2018-09-30 15:08:41

2009-06-08 20:13:36

Eclipse自定义控

2017-02-17 09:37:12

Android自定义控件方法总结

2015-02-11 17:49:35

Android源码自定义控件

2009-08-03 13:39:46

C#自定义用户控件

2009-08-03 13:34:06

自定义C#控件

2015-02-12 15:33:43

微信SDK

2021-11-18 13:40:50

物联网人工智能IoT

2023-01-06 11:17:44

戴尔

2010-06-08 20:42:24

淘宝网钓鱼欺诈

2015-02-12 15:38:26

微信SDK

2009-09-03 13:34:03

.NET自定义控件

2010-08-03 16:13:01

FlexBuilder

2009-07-28 09:32:41

ASP.NET自定义控

2009-08-10 14:16:59

ASP.NET自定义控

2015-01-22 15:59:07

Android源码日期时间控件SelectTime

2011-06-20 16:03:03

Qt 控件 鼠标

2024-09-11 14:46:48

C#旋转按钮
点赞
收藏

51CTO技术栈公众号