ASP.NET Web开发框架之五 控件扩展

作者:   出处:互联网   2015-07-05 23:01:51   阅读:2

当在Web页面中设计好表格布局之后,运用Enterpris Solution提供的框架,以可视化的方式绑定数据。首先,请在配置文件中添加如下的程序集引用,以方便框架运用反射找到当前项目所引用的实体层。

当在Web页面中设计好表格布局之后,运用Enterpris Solution提供的框架,以可视化的方式绑定数据。


 

首先,请在配置文件中添加如下的程序集引用,以方便框架运用反射找到当前项目所引用的实体层。


 

然后打开Visual Studio,在设计时面板中,选择一个控件。


 

image 


 

如上图所示,选择控件的DataBindingString属性,在属性面板中打开它。如果已经绑定了属性,它会自动高亮显示已经绑定的实体及其属性。这个属性的代码设计,是这样的


 

[Category(CategoryName.OPTIONS)]  [DefaultValue( )]  [Description( Data Binding )]  [Editor(typeof(QueryBindingTypeDialogEditor), typeof(UITypeEditor))]  public virtual string DataBindingString  {  get {  object obj = XState[ DataBindingString ];  return obj != null ? obj.ToString() :  ;  }  set {  XState[ DataBindingString ] = value;  }  } 


 

如代码所示,它提供了一个自定义的属性编辑器,也就是上图中们看到的Query Builder,绑定属性。


 

返回所需要绑定属性的关键代码如下所示,它读取实体层程序集并返回用户所选择的属性值


 

string path =  ;  IWebApplication webApp = (IWebApplication)provider.GetService(typeof(IWebApplication));  Configuration config = webApp.OpenWebConfiguration(true);  AppSettingsSection app = config.AppSettings;  path = app.Settings[ Assembly ].Value; 


 

这几句代码的含义,从当前Web项目中打开Web.config配置文件,并找到文章开头设置的实体层程序集。


 

代码生成


 

基于模板的代码生成器,例如Code Smith,给代码生成带来了极大的便利。Enterprise Solution相关的代码生成,均以Code Smith模板完成。熟悉ASP.NET的语法,应该可以很快熟悉Code Smith的语法并对它的生产力感到满意。


 

image


 

在最新版本的Code Smith 6.5中,支持.NET 3.x/4.0语法。还可以运用它的SDK,把代码生成功能集成到自己的开发工具中。比如,想制作一个批量代码生成的工具,直接调用Code Smith的模板文件:


 

public void RunTemplate(string templateFile,string connectionString,string tableName,string targetFile)  {  CodeTemplateCompiler compiler = new CodeTemplateCompiler(templateFile);  compiler.Compile();  if (compiler.Errors.Count == 0)  {  CodeTemplate template = compiler.CreateInstance();    DatabaseSchema database = new DatabaseSchema(new SqlSchemaProvider(), connectionString);  TableSchema tableSchema = database.Tables[tableName];   //如果都是字符串,应该要考虑bool,int,object  Dictionary string, object  dic = new Dictionary string, object  string[] paramterValues = rtfParameter.Lines;  foreach (string parm in paramterValues)  {  if (!String.IsNullOrEmpty(parm))  {  string[] values = Regex.Split(parm,  = );  string key = values[0];  object para =values[1].ToString().Trim();  if (string.IsNullOrEmpty(values[1]))  para = tableSchema;  dic.Add(values[0], para);  }  }  PropertyInfo[] pis = template.GetProperties();  foreach (PropertyInfo pi in pis)  {  object val=null;  if(dic.TryGetValue(pi.Name,out val))   template.SetProperty(pi, val);  }     if(File.Exists(targetFile))  File.Delete(targetFile);  using (StreamWriter writer = new StreamWriter(targetFile))  {  template.Render(writer);  writer.Flush();   }  }  } 


 

这个方法可以为代码生成带来诸多方便。比如以下面的参数调用之,则可以产生多个代码文件


 

RunTempate( Interface.cst , server=(local);uid=sa;pwd=holiday;database=TS , Employee , IEmployeeManager.cs)  RunTempate( Manager.cst , server=(local);uid=sa;pwd=holiday;database=TS , Employee , EmployeeManager.cs); 


 

每行产生一个代码文件,接口层和数据访问层立即产生完成。


 

数据字典


 

对于不变的数据字典,比如帐户的借方和贷方,程序员每天的工作分类项:Bug或Enhacement。对于这类不变的数据字典,Enterprise Solution以下面的方式处理它们。


 

先来看界面层的代码,看看最终的开发人员,需要以何种方式应用数据字典。以客户组别为例子


 

 ext:DropDownList ID= ddlCustomerGroup  Label= Customer Group  runat= server   /ext:DropDownList  


 

后台代码如下所示,也相当的简练


 

ddlCustomerGroup.InitializeValueListFromEnum(typeof(CustomeGroup)); 


 

在此,并没有直接扩展DropDownList的代码,而是加入扩展方法,它的实现方法如下所示


 

public static class DataBindingHelper  {  public static void InitializeValueListFromEnum(this ExtAspNet.DropDownList dropDownList, Type enumType)  {  dropDownList.Items.Clear();  foreach (KeyValuePair string, string  item in StringEnum.GetValueStringList(enumType))  {  ExtAspNet.ListItem listitem = new ExtAspNet.ListItem(item.Value, item.Key);  dropDownList.Items.Add(listitem);  }  }  


 

代码的意图相对简单,依据参数的枚举值分别产生ListItem达到生成数据字典项的目的。枚举CustomerGroup的定义


 

public enum CustomeGroup  {  [StringValue( Partner )]  [DisplayText( Partner )]  Partner,  [StringValue( Supplier )]  [DisplayText( Supplier )]  Supplier  } 


 

StringValue和DisplayText分别用于ListItem的ValueItem和TextItem,用于显示和实际的值。


 

对于需要从数据库中取出的数据字典,Enterprise Solution框架暂未提供很方便的方法来完成绑定。依照基本的方法,读取字段值,绑定到DropDownList中,过程也不复杂。


 

ExtAspNet控件扩展


 

ExtAspNet是一套优秀的控件,用它可以快速开发基于ExtJs的应用。虽然功能相当完善,但在细微处,仍需要稍微做一些调整,以满足框架的应用需要。


 

每一个需要绑定属性的控件,均加入了下面的属性,以方便绑定实体的属性。


 

[Category(CategoryName.OPTIONS)]  [DefaultValue( )]  [Description( Data Binding )]  [Editor(typeof(QueryBindingTypeDialogEditor), typeof(UITypeEditor))]  public virtual string DataBindingString  {  get {  object obj = XState[ DataBindingString ];  return obj != null ? obj.ToString() :  ;  }  set {  XState[ DataBindingString ] = value;  }  } 


 

其次,需要TextBox的文本标签是右对齐的,而不是左对齐,于是加入了下面的属性。


 

//fieldLabel居右对齐的问题   OB.AddProperty( labelStyle ,  text-align:right ); 


 

对于页面中的每个选项卡页面,需要在它关闭时,弹出提示确认窗口,于是修改代码


 

NODES.mainTabStrip.addTab({  'id': tabID,  'url': url,  'title': title,  'closable': true,  listeners: {   'beforeclose': conrirmTab   }  }); 


 

加了一个beforeclose确认,它的方法如下所示


 

function conrirmTab(e) {  Ext.MessageBox.show({  title: 'Confirm',  msg: 'Are you sure want to close  b ' + e.title + ' /b  ?',  buttons: Ext.MessageBox.YESNO,  icon: Ext.MessageBox.QUESTION,  fn: function (btn, text) {  if (btn == 'yes') {  NODES.mainTabStrip.remove(e);  }  }  });  return false;  } 


 

更精确的,们应该加在那些有数据修改的页面,如果页面被修改过,则弹出确认提示,否则可以直接关闭选项卡。


 

再来看看两个比较实用的脚本,关闭当前选项卡和关闭所有选项卡


 

//关闭活动的选项卡  function closeActivePanel() {  var tabpanel = Ext.getCmp(' %= mainTabStrip.ClientID % ');  var _activeTab = tabpanel.getActiveTab();  if (_activeTab.x_iframe_url ==  /Management/admin/default.aspx )  return;  tabpanel.remove(_activeTab);  }  //关闭所有选项卡  function closeAllPanel(){  var tabpanel = Ext.getCmp(' %= mainTabStrip.ClientID % ');  var _activeTab = undefined;  for(var i=0;i  tabpanel.items.length;i++)  {  _activeTab = tabpanel.items.items[i];  if (_activeTab.x_iframe_url!=undefined   _activeTab.x_iframe_url ==  /Management/admin/default.aspx )  continue;  tabpanel.remove(_activeTab);  i = 0;  }  tabpanel.doLayout();  } 


 

如果需要在后台代码中调用,可以这样调用之


 

string tab =  closeAllPanel(); ;  PageContext.RegisterStartupScript(tab); 


 

还有一些控制项,有的还未找到实现方法,一并列举如下


 

1  控制TextBox的输入长度。比如maxLength=6,只允许输入6个字符,第7个字符无法输入。当前控件仍然可以输入,只是会有验证提示错误。


 

2  只允许大写字母输入。有的控件,比如用户名,在C#.NET里面,MIS和mis的字母相同,但是比较equal时,如果不设置忽略大小写,则它们的值不等,但是在数据库里面,它们是相同的值。为避免这种情况,需要设置控件只允许输入大写字母,用户如果输入的是小写,则转化自动为大写。


 

3  对于Tab.cs #267行,这一行代码会有异常。如果前台JS打开多个选项卡,在页面刷新时,会抛出IndexOutOfRange异常,它的代码如下所示


 

// 对于非激活Tab,其中的Iframe需要延迟加载  if (this != tabStrip.Tabs[tabStrip.ActiveTabIndex])  {  OB.RemoveProperty( html );  OB.RemoveProperty( x_iframe_loaded );  OB.AddProperty( x_iframe_loaded , false);  } 


 

ActiveTabIndex的值是2或3,但是当前只有一个tab选项卡,于是抛出索引越界异常。


 

4 PageRefresh时,会关闭前台页面打开的选项卡。需要用cookie记住已经打开的选项卡,在PageRefresh后,再打开被迫关闭的选项卡,以减少用户困扰。


 

5 对ascx用户控件的支持。新版本的ExtAspNet已经内置了此功能。如果仍使用的是3.1.8版本,需要这样


 

foreach (UserGroupMenuTypeEntity usermenuType in menu.UserGroupMenuTypes)  {  function c = LoadControl( function.ascx ) as function;  c.LineBreakPlaceHolder.Text =GetTranslation(usermenuType.Description.Replace( ,  ));  c.DataList1.DataSource = usermenuType.UserGroupMenuDetails;  c.DataList1.DataBind();  ph.Controls.Add(c);  Literal liter = new Literal();  liter.Text =  br / ;  ph.Controls.Add(liter);  } 


 

加载用户自定义控件。因为Web不同于WinForms,Web的类型定义并不包含资源,图片,控件,还必须引用页面ASPX/ASCX文件,C/S类型的继承则包含类型的方法,及其界面控件,相对方便很多。


 

6 Excel导入导出的支持。官方的例子中已经包含EXCEL导出功能,但没有导入功能,仍然需要提供Web方式下的EXCEL数据导入功能。

Copyright© 2006-2015 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 渝ICP备12000264号 法律顾问:元炳律师事务所
客服软件
live chat