Code never lies!


                                                   -- iret

导航

How To: 为组件属性添加Design-time多语言支持

Posted on 2005-03-28 11:16  iret  阅读(1880)  评论(3编辑  收藏  举报

    所谓组件属性的 design-time 多语言支持,是让你的组件在使用的时候对不同语言版本的IDE显示对应的语言版本描述。 例如,很多专业的组件都有这样的属性,你在中文版的 .net studio 看到的属性描述都是中文的, 而在日文下看到的描述则是日文的。
    在编写 .Net Component 的时候,如何添加 design-time 的多语言支持呢?

    Anyway, "Imitation is the sincerest form of flattery". 我们来看看微软是怎么做。 
    
    以下是微软类库中CheckBox的伪代码片断分析,
    public class CheckBox 
    {
     ....
       // Properties   
      [SRDescription("CheckBoxAutoCheckDescrKey")]
      public bool AutoCheck { get; set; }
      [SRDescription("CheckBoxCheckAlignDescrKey")]
      public ContentAlignment CheckAlign { get; set; }
      [SRDescription("CheckBoxCheckedDescrKey")] 
      public bool Checked { get; set; }
     ...
    }    

    通过反射机制,.Net Studio IDE 会从组件属性中声明的 SRDescription 中获取描述字符串,然后在属性窗口中显示。  
    SRDescription 是 类 SRDescriptionAttribute 的实例。 SRDescriptionAttribute 继承了 DescriptionAttribute, 提供了获得本地化的描述的实现 -- public override string Description { get; },   伪码如下:
    // the declamation of the class SRDescriptionAttribute 
    class SRDescriptionAttribute : DescriptionAttribute 
    {
      // constructor descripton key specified the key of the resouce string.
      public SRDescriptionAttribute(string descriptionKey);

      // Return the localized description string, according to the description_Key get the description from the assembly resource source.
      public override string Description { get; }
    ...

     }
    
    简而言之,为了获得多语言支持,只要在 SRDescriptionAttribute 类的 Description 的实现中,根据不同的语言获取相对应的描述字符串便可以了。 
    
    那么接下来,我们要如何做呢?
    
    首先,依上所述,从 DescriptionAttribute 通过继承,创建一个我们自己的 ResourceDescriptionAttribute。由于这个类是设计时用的,我们可以把它标记为 internal,阻止外面的非法访问。
    
    重写 Description 的实现, 根据不同的语言获得不同的描述字符串。 根据具体情况,一般可以把 Default 的语言类型相对应的资源文件嵌入到组件的Main Assembly里面,作为fall back资源,而把其他语言的资源文件独立编译到另外的一个专门提供本地化资源的 Resource Assembly。 Description的实现里面做一个小小的处理,根据当前的语言版本去查找 Resource Assembly, 如果没有发现当前环境相应的语言的资源,或者无法读取 Resource Assemly,就应该采用Main Assembly的 fall back 资源文件。 这也是称之为 fall back 资源文件的来由, (fall back 有些 backup 的含义)。

    添加资源文件。 为不同的组件属性添加不同的描述字符串。 注意,不同语言版本的资源文件要保持Key的一致性。 

    例如,比较著名的 Crystal Report 大体也是就是这样实现的。 查看本机的 GAC, 你应该可以找到这两个 Assembly, CrystalDecisions.Web.dll 和 CrystalDecisions.Web.resources.dll。 其中,CrystalDecisions.Web.dll 就是上面提到的 Main Assembly, 里面包含了 Web form 下的组件实现,以及 Default 语言的资源文件也就是 fall back 资源, CrystalDecisions.Web.resources.dll 就是Resource Assembly, 提供了相应的本地化资源文件。 

    当然这个是很 professional 的做法,若你的 Component 不必要那么强调国际化本地化的支持,干脆直接使用DescriptionAttribute相应的描述 hard code 到类实现就可以了。 毕竟,在变化到来之前,任何的提前设计,都应先假设为过度的。
    例如:
     [Description("hard code your description here")
     public Image MyImage {
        get {
           // Insert code here.
           return image1;
        }
        set {
           // Insert code here.
        }
     }

    有关如何根据操作资源以及资源本地化支持,已经超过了本文的讨论范畴,请参阅msdn。