程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 實現 ActiveReports 的本地化!

實現 ActiveReports 的本地化!

編輯:.NET實例教程

用過 ActiveReports for .Net (以下簡稱AR)的都知道它的優勢(可代碼化),這樣就提供了很多報表功能開發的空間給程序員。

不多說了,下面將通過我的一個EPR軟件來介紹一下實現 AR 2.0 的報表本地化功能(主要通過UI貼圖+講解方式):

開發環境:VS2005 .Net 2.0 + C# + SQL2005 + AR 2.0

=========================================================

講解一下如何實現這幾種本地化語言: 

1,報表預定義(快速!) [Default] 

   就是指實例化報表時不應用本地化設置;

2,CIMS本地化設置(推薦!)(System)

   隨主系統的本地化設置一樣;

3,簡體中文(Chinese SimplifIEd)

4,繁體中文(Chinese Traditional)

ReportLocal 類 定義一個屬性:



public bool CanActive
{
  get{ return m_canActive;}
  set{ m_calActive = value;}
}

這個屬性在ReportLocal類實例化代入,來自主系統用戶權限控制,如果你的程序沒有相關權限控制可忽略。

這個Active屬性用來表示將要使用的本地化語言:



 /// <summary> 
 /// 獲取當前報表本地化設置(''CIMS本地化設置'' 除外) 
 /// </summary> 
public ReportLocalizableEnum Active 

   get 
   { 
        if (CanActive == false)  return ReportLocalizableEnum.Default; 
        if (m_active == ReportLocalizableEnum.System) m_active = GetReportLocalizableWithSystem;

        return m_active;  //來自存儲參數
  } 

 

這些屬性,函數很關鍵,主要收集可以本地化的報表組件(未定義DataFIEld屬性的):



    /// <summary> 
    /// 要本地化的報表控件集合,用於OnInitControlsCollection()函數。 
  /// 參數:Key = Control.Name
    /// 參數:Value = 控件(Label;TextBox,CheckBox...) 
    /// </summary> 
public Hashtable Collection { get { return rptControls; } } 

public Hashtable CreateReportControls(DataDynamics.ActiveReports.ActiveReport rpt, string sectionNameOrType) 

    if (rpt == null)  return null; 

    Hashtable ctrls = new Hashtable(); 
    Section rs = null; 
    
    bool all = (sectionNameOrType == UnknownSection || string.IsNullOrEmpty(sectionNameOrType)); 
    //所有報表區域 
    if (all == false) { 
       
        try 
        { 

            SectionType type = (SectionType)System.Enum.Parse(typeof(SectionType), sectionNameOrType, true); 

            foreach ( rs in rpt.Sections) 

            { 
                if (rs.Name == sectionNameOrType)   break; 
                 if (type == rs.Type)    break;
            }

        }
        catch { 
                all = true; 
                break; 
            } 
    } 
    
    if (all || (rs == null)) { 
        foreach ( rs in rpt.Sections) 


        { 
            AddControlsInfo(rs, ctrls); 
        } 
    } 
    else {AddControlsInfo(rs, ctrls); } 
    
    return ctrls; 


private void AddControlsInfo(Section section, Hashtable collections) 

    SectionType type = section.Type; 
    ARControl ctrl; 
    foreach ( ctrl in section.Controls) { 
        if (string.IsNullOrEmpty(ctrl.DataFIEld) == false)   continue; 
          
        //只收集沒有是定義DataFIEld屬性的組件! 
    ReportControlInfo ctrlInfo = null; 
        if (ctrl is Label) 
            Label lab = (Label)ctrl; 
            ctrlInfo = new ReportControlInfo(lab.Text); 
        } 
        
        else if (ctrl is TextBox) { 
            TextBox txt = (TextBox)ctrl; 
            if (string.IsNullOrEmpty(txt.Text))  continue; 

            ctrlInfo = new ReportControlInfo(txt.Text); //TextBox類型必須是設置了Text的!
        } 
        else if (ctrl is CheckBox) { 
            CheckBox chk = (CheckBox)ctrl; 
            if (string.IsNullOrEmpty(chk.Text))    continue; 
           
            ctrlInfo = new ReportControlInfo(chk.Text); //CheckBox類型必須是設置了Text的! 
            
        } 
        
        if ((ctrlInfo != null)) 
        { 
            ctrlInfo.DataField = this.GetDataFIEld(ctrlInfo.Text, string.Empty); 
            ctrlInfo.Section = type; 
            ctrlInfo.Parent = ctrl.Parent; 
            collections.Add(ctrl.Name, ctrlInfo); 
        } 
        
    } 


/// <summary> 
/// 根據組件的Name返回關聯本地化設置的‘字段名’,僅判斷一些常用的。 
/// </summary> 
/// <param name="controlText">組件.Text</param> 
/// <param name="defaultFIEld">默認使用的‘字段名’,一般為空,需要後續修正</param> 
protected string GetDataField(string controlText, string defaultFIEld) 

    if (controlText.IndexOf("ted By") > -1) { 
        return DBColumns.CreatedBy; 
    } 
    else if (controlText.IndexOf("red By") > -1) { 
        return DBColumns.PreparedBy; 
    .......//根據你的報表來添加判斷,主要是用於後面的BatchCreate功能,避免手功添加


這是ReportControlInfo類(用於收錄組件的相關參數):



public class ReportControlInfo 
...{ 
    protected string m_text; 
    protected string m_dataFIEld; 
    protected object m_section; 
    protected object m_parent; 
    public ReportControlInfo(string text) 
...{ 
        m_text = text; 
    } 
    public ReportControlInfo(string text, object section) 
    ...{ 
        m_text = text; 
        m_section = section; 
    } 
    public ReportControlInfo(string text, string dataFIEld) 
    ...{ 
        m_text = text; 
        m_dataField = dataFIEld; 
    } 
    
    /**//// <summary> 
    /// 獲取或設置 組件預定義了的文本 
  /// </summary> 
 string Text ...{ 
        get ...{ return m_text; } 
        set ...{ m_text = value; } 
    } 
    
    /**//// <summary> 
    /// 獲取或設置 用於關聯本地化設置的‘字段名’ 
  /// </summary> 
    public string DataFIEld ...{ 
        get ...{ return m_dataFIEld; } 
        set ...{ m_dataFIEld = value; } 
    } 
    
    /**//// <summary> 
    /// 獲取或設置 組件的父容器(PageHeader,GroupHeader...),一般可不設置 
  /// </summary> 
    public object Parent ...{ 
        get ...{ return m_parent; } 
        set ...{ m_parent = value; } 
    } 
    /**//// <summary> 
    /// 獲取或設置 組件所在的節(Report.Section),可以是SectionName OR SectionType 
    /// </summary> 
Section ...{ 
        get ...{ return m_section; } 
        set ...{ m_section = value; } 
    } 
    

=================================

下面將是實現“報表本地化關聯”功能的核心:

為於實現報表同主系統使用一致的本地化定義,下面部分是必須的!

系統的本地化資源編輯器(由於此ERP的應用關系,編輯器中增加了對應用人的權限控制),源代碼不提供:

這是 關聯系統本地化設置 的報表本地化配置器:

解釋一下各字段作用:

所屬區域:指要本地化的組件所在的Section,如果為空,則為公共設置,任何報表都會搜索這些關聯設置;

字段名:一般為數據表的ColumnName,要同“本地化編輯器”裡的DataFIEld定義一致;

組件名:將本地化的AR.Control,應於實際報表設計時一致,如果報表做了更改,可使用“批量修復”功能來自動修復refContrlName;

默認文本:AR.Control 預定義的Text,如果用戶想始終使用這個DefaultText,只需要定義後鉤選“僅使用默認標題”;

備注:不用解釋了。

“報表效果預覽”只是應用了最上面的參數設置。

下面,錄制了一個“批量創建”報表組件的本地化關聯設置的動畫(文件太大!只能用GIF格式上傳了,UI有失真):

索引關聯設置類:



using System;
using System.Text;
using System.Data;
using System.Data.SqlClIEnt;

namespace CIMS.Report
...{
    public class ReportsLocalization : IDisposable
        Const#region Const
        public static string[] Sections
        ...{
            get
            ...{
                return new string[] ...{ 
                    "ReportHeader",
                    "PageHeader",
                    "GroupHeader",
                    "Detail",
                    "ReportFooter",
                    "PageFooter",
                    "GroupFooter",
         "Unknown!"};
            }
        }

        public const string COL_DATAFIELD = "字段名";

        public const string COL_REPORTID = "報表編碼";
        public const string COL_SECTIONNAME = "所屬區域";
        public const string COL_CONTROLNAME = "組件名";
        public const string COL_CONTROLTEXT = "默認文本";

        public const string DATATABLE_NAME = "ReportsLocalization";
        #endregion

        Variables#region Variables
        protected string m_reportID = string.Empty;
        protected string m_activeDBForm = string.Empty;

        protected Document.ReportLocalizable reportLocal = null;
        protected EnToolTips refLocal = null;
        protected DataVIEw dv = null;
        #endregion

        Init#region Init
<summary>
        /// 實例化本地化報表關聯設置加載類
        /// </summary>
        /// <param name="reportID">報表枚舉成員(ReportsAssembly.MemberID)</param>
        public ReportsLocalization(string reportID):this(reportID,string.Empty) ...{ }
        /**//// <summary>
        /// 實例化本地化報表關聯設置加載類
        /// </summary>
        /// <param name="reportID">報表枚舉成員(ReportsAssembly.MemberID)</param>
        /// <param name="dbFormName">將應用自定義本地化報表的數據模塊(如果為空,則表示將應用到所有模塊)</param>
        public ReportsLocalization(string reportID, string dbFormName)
        ...{
            if (string.IsNullOrEmpty(reportID)) ...{ throw ne("報表成員未指定!");  }

            m_reportID = reportID;
            m_activeDBForm = dbFormName;

            this.OnInit();
        }

        protected void OnInit()
        ...{
            if (Common.Common.get_CIMSReadOnly(false)) return;

            reportLocal = new CIMS.Document.ReportLocalizable(ActiveDBForm);
            refLocal = new EnToolTips(ActiveDBForm);
            this.FillData();

        }

        protected void FillData()
        ...{
            string paramReportID = "@ReportID";
            SqlDataAdapter sda = new SqlDataAdapter("SELECT ReportID AS " + COL_REPORTID + ", DataField AS " + COL_DATAFIELD + ", SectionName AS " + COL_SECTIONNAME + ", ControlName AS " + COL_CONTROLNAME + ", ControlText AS " + COL_CONTROLTEXT + ", Lock AS " + Utils.LOCK + " FROM " + DATATABLE_NAME + " Where ReportID Is Null Or ReportID = " + paramReportID + " Order By ReportID", Common.SqlHelper.ConnectionBase.CONCIMS);
 &n     sda.SelectCommand.Parameters.Add(paramReportID, SqlDbType.VarChar, 50).Value = this.ReportID;

            DataTable dt = new DataTable(DATATABLE_NAME);
            using (sda)
            ...{
                dt.BeginLoadData();
                sda.Fill(dt);
                dt.EndLoadData();
            }

            dv = dt.DefaultVIEw;
        }

        #endregion

        Properties#region PropertIEs
        /**//// <summary>
        /// 獲取 本地化定位器
        /// </summary>
EnToolTips Localizer ...{ get ...{ return refLocal; } }
        /**//// <summary>
        /// 獲取 報表枚舉成員(ReportsAssembly.MemberID)
        /// </summary>
        public string ReportID ...{get ...{ return m_reportID; }}
        /**//// <summary>
        /// 獲取將應用報表本地化關聯設置的數據模塊(如果為空,則表示將搜索所有模塊的本地化設置資源)
        /// </summary>
        public string ActiveDBForm ...{ get ...{ return m_activeDBForm; } }

        #endregion

#region Localizable
        /**//// <summary>
        /// 獲取報表組件(按Control.Name)的本地化關聯設置。不存在設置就返回空:String.Empty
        /// </summary>
        /// <param name="ctrlName">組件名</param>
        /// <returns>不存在設置就返回空:String.Empty</returns>
        public string GetLocalText(string ctrlName)
        ...{
            string nameFilter =  COL_CONTROLNAME + "=''" + ctrlName + "''";
            dv.RowFilter = nameFilter;
            if (dv.Count == 0) return string.Empty;

            dv.RowFilter += " And " + COL_REPORTID + "=''" + ReportID + "''";//報表成員優先
            if (dv.Count > 0) return GetActiveLocalText(dv[0]);
        
            dv.RowFilter = nameFilter + " And " + COL_REPORTID + " IS Null";//搜索公共成員
            if (dv.Count > 0) return GetActiveLocalText(dv[0]);

            return string.Empty;
        }

        protected string GetActiveLocalText(DataRowVIEw drv)

            bool useDefaultText = Convert.ToBoolean(Common.Common.IsNull(drv[Utils.LOCK], false));
            if (useDefaultText) return Common.Common.IsNull(drv[COL_CONTROLTEXT],drv[COL_DATAFIELD]).ToString();//使用默認文本

            string dataField = Common.Common.IsNull(drv[COL_DATAFIELD], string.Empty).ToString();
            switch (reportLocal.Active)
            ...{
                case ReportLocalizableBase.ReportLocalizableEnum.ChineseSimplifIEd:
                    return refLocal[dataFIEld];
                case ReportLocalizableBase.ReportLocalizableEnum.ChineseTraditional:
                    return refLocal.ConvertZNString(refLocal[dataFIEld]);
                case ReportLocalizableBase.ReportLocalizableEnum.English:
                    return refLocal.IsExist(dataFIEld) ? refLocal.EnToolTip : string.Empty;
                default:
                    return string.Empty;
            }
        }

<summary>
        ///// 獲取報表組件(按Control.Text)的本地化關聯設置
        ///// </summary>
        ///// <param name="ctrlText">組件的預設文本</param>
        ///// <returns></returns>
        //public string GetLocalText(string ctrlText)
        //{
        //    dv.RowFilter = COL_CONTROLNAME + "=''" + ctrlName + "''";
        //}

        //protected bool SetRowFilter(string filter, bool ctrlNameFilter)
        //{

        //    dv.RowFilter = (ctrlNameFilter ? COL_CONTROLNAME : COL_CONTROLNAME) + "=''" + filter + "''";

        //}

        #endregion

        IDisposable#region IDisposable

        public void Dispose()
        ...{
            if (Localizer != null) Localizer.Dispose();
            if (dv != nul.Dispose();
        }

        #endregion
    }
}

通過上面一些定義,就可以在實例化報表時實現本地化報表了!

先收集本地化組件到Collection,然後遍歷集合並:



//GetLocalText函數很重要!

rptTest rpt = new rptTest(...);

ReportLocal reportLocal = new ReportLocal(true);

reportLocal.OnInitControlsCollection();

IDictionaryEnumerator IE = collection.GetEnumerator();
while (IE.MoveNext())
{
    string controlName = IE.Key.ToString();
    string localText =  reportLocal.GetLocalText(controlName);//得到本地化資源
  if(string.IsNullOrEmpty(localText)) continue;

    ARControl ctrl= (ARControl)((ReportControl)IE.Value).Control;
    if( ctrl is Label)
     
    ((Label)ctrl).Text= localText ;//設置Text屬性完成本地化
  else if ......

}

最終報表本地化預覽:

 


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved