打造可持续发展的事业

事业像系统的框架,要稳定、可扩展,同样需要精心设计的!

DNN开发中的一些细节--DNN自定义控件的本地化

 

1)模块的本地化和ASP.Net2的本地化不尽相同

建立一个View Module,我拖放了两个控件,一个是常规的Label,还有一个是DNN中的labelcontrol




画面如下:

 

利用VS的工具自动生成资源。

 

它将会在App_LocalResources目录下生成一个对应的resx文件

 


文件内容如下:

我修改第一行的Value

ascx文件也发生了修改

Label 中加入了meta:resourcekey=”label1Resource1”

运行后我们发现Label1的标签并没有发生修改。查阅了相关资料,表明DNNASP2.0Localization是不兼容的。为了证实这一点,我重新修改了代码:

我加入几乎是相同的一行,但是去掉了resourcekey前面的meta。运行



发现第一个
Label没有Localization,而第二个由于少了meta就支持了!结论:

DNNLocalizationASP.Net20有些差异,用自动生成的resx的工具是需要修改调整的。

 

我们发现在LabelControl也显示了相应的Localization的字符,那时因为我在对应的ascx中加入了不带Metaresourcekey标签。

 

2)作为模块内部的控件的本地化

 

我们将上述的TestControl变成一个Control

 

public partial class DesktopModules_ABCTest_TestControl : PortalModuleBase

{

    protected void Page_Load(object sender, EventArgs e)

    {

 

    }

}

改为

public partial class DesktopModules_ABCTest_TestControl : UserControlBase

{

    protected void Page_Load(object sender, EventArgs e)

    {

 

    }

}

继承自 UserControlBase

 

我们将这个作为一个自定义控件加入到ViewABCTest.ascx中。ViewABCTest.ascx中原有一个Label并定义了其Resourcekey,以及在资源文件中加入Value为“Parent Label


我们修改一下ModuleView模块。

 

运行,结果发现


 

作为控件(继承自UserControlBase)的TestControl 并没有像它作为模块(继承自PortalModuleBase)被本地化。

 

我想起了urlControl,它是一个控件,它有独立的resx本地化文件,它的确能本地化。



它采用了什么特殊处理?

 

我拖放一个urlcontrol的确能够本地化为中文

比如“连接类型”,后台代码如下:

<asp:label id="lblURLType" runat="server" enableviewstate="False" resourcekey="Type" CssClass="NormalBold"></asp:label>

resx文件中:



这也就是对于控件的
Resx文件是能够生效的。

 

可是这个urlcontrol也使继承自UserControlBase的。他们的差异在哪里呢?

在所有的函数中都找不到踪迹,包括Pageload等等,这个神秘的Localization在哪里呢?最后发现它有一个LocalResourceFile属性:

 

        Public Property LocalResourceFile() As String

            Get

                Dim fileRoot As String

 

                If _localResourceFile = "" Then

                    fileRoot = Me.TemplateSourceDirectory & "/" & Localization.LocalResourceDirectory & "/URLControl.ascx"

                Else

                    fileRoot = _localResourceFile

                End If

                Return fileRoot

            End Get

            Set(ByVal Value As String)

                _localResourceFile = Value

            End Set

        End Property

 

估计是这个在作怪,看了几个控件都有这个属性:

 

我在Solution中查找LocalResourceFile。在几十个结果中抓住了一个“嫌疑犯”。

 

        ''' <summary>

        ''' <para>ProcessControl peforms the high level localization for a single control and optionally it's children.</para>

        ''' </summary>

        ''' <param name="c">Control to find the AttributeCollection on</param>

        ''' <param name="affectedControls">ArrayList that hold the controls that have been localized. This is later used for the removal of the key attribute.</param>             

        ''' <param name="includeChildren">If true, causes this method to process children of this controls.</param>

        Friend Sub ProcessControl(ByVal c As Control, ByVal affectedControls As ArrayList, ByVal includeChildren As Boolean, ByVal ResourceFileRoot As String)

在这个函数中对标准的控件进行了翻译(本地化:找到对应的LocalResource文件,取出其值)。比如对于Label

If TypeOf c Is Label Then

                    Dim ctrl As Label

                    ctrl = DirectCast(c, Label)

                    If value <> "" Then

                        ctrl.Text = value

                    End If

                End If

这里就是对Lable.Text进行本地化赋值。Value来之何方呢?

Dim key As String = GetControlAttribute(c, affectedControls)

            If Not key Is Nothing Then

                'Translation starts here ....

                Dim value As String

                value = Services.Localization.Localization.GetString(key, ResourceFileRoot)

可以理解为value就是在对应的Resource文件中找到该KeyKey又是通过GetControlAttribute函数来提取的,GetControlAttribute函数应该是得到一个控件的属性(集?)。

 

到此,我们基本明白了,在DNN中自定义控件如果需要本地化,应该实现一个LocalResourceFile只读属性。在对应的文件中加入

public string LocalResourceFile

    {

        get

        {

            return DotNetNuke.Services.Localization.Localization.GetResourceFile(this, "TestControl.ascx");

        }

}

运行!

OK

 

结论:

DNN中自定义控件如果需要本地化,应该实现一个LocalResourceFile只读属性。

 

好像这个机制改进的余地还是有的,比如用一个Attribute就可以搞定:

[Localizable(“localresourcefile”)]//缺省为“类名.resx

Public class MyDNNControl:UserControlBase

{

……

}

 

posted on 2006-04-06 22:59  PM2004  阅读(1306)  评论(2编辑  收藏  举报

导航