asp.net mvc下通用连动下拉框剖析(一)--基础数据Model们(最新完善版)

ASP.NET MVC级联下拉框解析

导读:

代码可以在http://files.cnblogs.com/bighuiwolf/Chinasoft.rar下载。

第一篇:http://www.cnblogs.com/bighuiwolf/archive/2010/07/10/1774871.html

第二篇:http://www.cnblogs.com/bighuiwolf/archive/2010/07/10/1774920.html

第三篇:http://www.cnblogs.com/bighuiwolf/archive/2010/07/10/1774955.html

 

本篇为第一篇

 

前几天发了一篇asp.net mvc下连动下拉框的文章,今天开始一步步分析其代码。

---------------------------

补 整体思路:

我有一个理念,就是程序员应该尽量用代码来说话,不要光用嘴说话,这样才能言之有物,很多时候,一行代码可以胜过千言万语。

本系列文的写作方式也是贴全部核心代码,再加解释说明。

本系列分三篇,本文是第一篇,介绍级连下拉框所需要的基础数据的定义。第二篇介绍Form需要的数据定义。第三篇介绍例子代码。

整体的介绍顺序是自底向上先局部后全局的,如果有人喜欢自顶向下的研究,可以从第三篇最后一行倒着向上看,完全没有问题。

---------------------------

1. Model:

现在流行模型驱动设计,所以我从这里开始。假设要做一个国家、城市、区(县)、街道,这样的四级下拉框。作为一个Demo,我用XML文件作为我的数据存储方式。Demo的目标是建立一个页面,上面有国家、城市、区(县)、街道四个下拉框和一个代表其它信息的Other Infomation。其中的级联下拉框有相当一部分是可重复使用的通用代码,读懂程序的人都应该可以明白哪些是需要在项目中根据需要重写的吧。

 

废话不多说了,下面是顶级下拉框的基类,可以把顶级下拉框的共有的部分放进去(本例中它是国家类的基类):

 1  public   abstract   class  SelectListProviderBase
 2      {
 3           public  SelectList GetSelectList()
 4          {
 5               return  GetSelectList( null );
 6          }
 7 
 8           public  SelectList GetSelectList( int ?  selectedValue)
 9          {
10               return  GetSelectList(selectedValue,  true );
11          }
12 
13           public  SelectList GetSelectList( int ?  selectedValue,  bool  AddEmpty)
14          {
15               string  file  =  HttpContext.Current.Server.MapPath(DataFile);
16              var values  =  from c  in  XElement.Load(file).Elements(RootElement)
17                           select  new  KeyValuePair < string string > (c.Attribute( " id " ).Value, c.Attribute( " name " ).Value);
18 
19              var list  =  values.ToList();
20               if  (AddEmpty)
21              {
22                  RepositoryHelper.AddEmpty(list);
23              }
24               return  RepositoryHelper.GetSelectList(list, selectedValue);
25          }
26 
27           public   abstract   string  DataFile {  get ; }
28           public   abstract   string  RootElement {  get ; }
29      }

 

下面是国家类: 

 1 
 2       public   class  Countries : SelectListProviderBase
 3      {
 4           public   override   string  DataFile
 5          {
 6               get
 7              {
 8                   return   " ~/App_Data/countries.xml " ;
 9              }
10          }
11 
12           public   override   string  RootElement
13          {
14               get
15              {
16                   return   " country " ;
17              }
18          }
19      }

 

我们经常会遇到根据父ID获取子下拉框数据的需求,下面是我定义的一个接口,它可以作为所有有父级的下拉框的数据源接口:

 

1 
2       public   interface  IHasParent
3      {
4          SelectList GetSelectListByParentId( int  parentId);
5          SelectList GetSelectListByParentId( int  parentId,  int ?  selectedValue);
6          SelectList GetSelectListByParentId( int  parentId,  int ?  selectedValue,  bool  AddEmpty);
7      }

 

城市、区(县)、街道都要实现这个接口。我只要设计一个基类,实现该接口,然后基类的各子类指出每个类所用的XML文件和根元素即可:

 

 1 
 2       public   abstract   class  HasParentBase : IHasParent
 3      {
 4           #region  IHasParent Members
 5 
 6           public   virtual  SelectList GetSelectListByParentId( int  parentId)
 7          {
 8               return  GetSelectListByParentId(parentId,  null );
 9          }
10 
11           public   virtual  SelectList GetSelectListByParentId( int  parentId,  int ?  selectedValue)
12          {
13               return  GetSelectListByParentId(parentId, selectedValue,  true );
14          }
15 
16           public   virtual  SelectList GetSelectListByParentId( int  parentId,  int ?  selectedValue,  bool  AddEmpty)
17          {
18              var values  =  GetData(parentId);
19              var list  =  values.ToList();
20               if  (AddEmpty)
21              {
22                  RepositoryHelper.AddEmpty(list);
23              }
24               return  RepositoryHelper.GetSelectList(list, selectedValue);
25          }
26 
27           #endregion
28 
29           public   abstract   string  DataFile {  get ; }
30           public   abstract   string  RootElement {  get ; }
31 
32           public  IEnumerable < KeyValuePair < string string >>  GetData( int  parentId)
33          {
34               string  file  =  HttpContext.Current.Server.MapPath(DataFile);
35              var values  =
36                  from c  in  XElement.Load(file).Elements(RootElement)
37                   where  c.Attribute( " parentId " ).Value  ==  parentId.ToString()
38                  select  new  KeyValuePair < string string > (c.Attribute( " id " ).Value, c.Attribute( " name " ).Value);
39               return  values;
40          }
41      }

 

拿Cities来说(Suburbs和Streets都一样,都继承HasParentBase): 

 1 
 2       public   class  Cities : HasParentBase
 3      {
 4           public   override   string  DataFile
 5          {
 6               get
 7              {
 8                   return   " ~/App_Data/cities.xml " ;
 9              }
10          }
11 
12           public   override   string  RootElement
13          {
14               get
15              {
16                   return   " city " ;
17              }
18          }
19      }

 

至此,所有基础数据都定义完了,下一节介绍页面中用到的数据,即FormModel们。

大家有什么不满,尽可扔鸡蛋,砖头的不要。

 

PS:国家数据XML:

1  <? xml version = " 1.0 "  encoding = " utf-8 "   ?>
2  < countries >
3     < country id = " 0 "  name = " USA " />
4     < country id = " 1 "  name = " Britain " />
5  </ countries >

 

 

城市的数据(Suburbs和Streets与Cities类似,就不重复了):

1  <? xml version = " 1.0 "  encoding = " utf-8 "   ?>
2  < cities >
3     < city parentId = " 0 "  id = " 0 "  name = " New York " />
4     < city parentId = " 0 "  id = " 1 "  name = " Washington " />
5     < city parentId = " 1 "  id = " 2 "  name = " London " />
6  </ cities >

 

 

posted on 2010-07-10 15:06 灰灰狼 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/bighuiwolf/archive/2010/07/10/1774871.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值