灰灰狼

灰灰的狼

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

导读:

代码可以在https://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

 

本篇为第二篇

 

该说FormModel了,最核心的就是DropDownList需要用到的数据了,想一想,它需要哪些东东呢?可以先看下代码,稍有点复杂,不要急,后面再做逐步的分析,下面是代码:

  1 
  2     public class DdlFormModel
  3     {
  4         public DdlFormModel()
  5         {
  6         }
  7 
  8         public DdlFormModel(string ddlKeyConfig, string ddlName, SelectList ddlData)
  9         {
 10             DdlKeyConfig = ddlKeyConfig;
 11             DdlName = ddlName;
 12             DdlData = ddlData;
 13         }
 14 
 15         public string DdlKeyConfig { getset; }
 16         public string DdlName { getset; }
 17         public SelectList DdlData { getset; }
 18         private string _onchange;
 19         public object HtmlAttributes
 20         {
 21             get
 22             {
 23                 if (!string.IsNullOrEmpty(_onchange))
 24                     return new { onchange = _onchange };
 25                 return null;
 26             }
 27         }
 28 
 29         public void SetChilds(string childIds, string childKey)
 30         {
 31             if (childIds != null && childIds.Length > 0)
 32             {
 33                 string[] childIdArray = childIds.Split(',');
 34                 string subChildIds = null;
 35                 int idx = childIds.IndexOf(",");
 36                 if (idx > -1)
 37                     subChildIds = childIds.Substring(idx + 1);
 38 
 39                 StringBuilder sb = new StringBuilder();
 40                 for (int i = 1; i < childIdArray.Length; i++)
 41                 {
 42                     sb.AppendFormat("ClearChilds('{0}');", childIdArray[i]);
 43                 }
 44                 sb.AppendFormat("GetChilds(this.id, '{0}', '{1}', '{2}', '{3}');"
 45                     ,DdlKeyConfig, childIdArray[0], childKey, subChildIds);
 46 
 47                 if (_onchange == null)
 48                 {
 49                     _onchange = sb.ToString();
 50                 }
 51                 else
 52                 {
 53                     _onchange += sb.ToString();
 54                 }
 55             }
 56         }
 57 
 58         public static DdlFormModel CreateInstance(
 59             string ddlKeyConfig
 60             , string ddlName
 61             , IHasParent hasParent
 62             , int parentId
 63             , int? selectedValue
 64             , string childIds
 65             , string childKey)
 66         {
 67             SelectList selectList = hasParent.GetSelectListByParentId(parentId, selectedValue);
 68             var instance = new DdlFormModel(ddlKeyConfig, ddlName, selectList);
 69             if (!string.IsNullOrEmpty(childIds))
 70             {
 71                 instance.SetChilds(childIds, childKey);
 72             }
 73             return instance;
 74         }
 75 
 76         public static DdlFormModel CreateInstance(
 77             string ddlKeyConfig
 78             , string ddlName
 79             , IHasParent hasParent
 80             , int parentId
 81             , int? selectedValue)
 82         {
 83             return CreateInstance(ddlKeyConfig, ddlName, hasParent, parentId, selectedValue, nullnull);
 84         }
 85 
 86         public static DdlFormModel CreateInstance(
 87             string ddlKeyConfig
 88             , string ddlName
 89             , SelectList selectList
 90             , string childIds
 91             , string childKey)
 92         {
 93             var instance = new DdlFormModel(ddlKeyConfig, ddlName, selectList);
 94             if (!string.IsNullOrEmpty(childIds))
 95             {
 96                 instance.SetChilds(childIds, childKey);
 97             }
 98             return instance;
 99         }
100     }

 

 

FormModel跟View要一块儿看才清楚,我定义了以下PartialView即用户控件来作为DropDownList的呈现逻辑:

1 <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Chinasoft.Models.DdlFormModel>" %>
2 <% if (Model != null)
3    { %>
4 <%= Html.DropDownList(Model.DdlName, Model.DdlData, Model.HtmlAttributes)%>
5 <% }
6    else
7    { %>
8 Model为空
9 <% } %>|<%= DateTime.Now %>

 

可以看到,里面用到了DdlFormModel的DdlName, DdlData, HtmlAttributes三个属性。它的构造函数里有三个参数(string ddlKeyConfig, string ddlName, SelectList ddlData),可能后两个参数大家能看明白,ddlName就是控件名,ddlData就是从SelectListProviderBase(顶级)或IHasParent(子级)获取到的数据。而ddlKeyConfig不容易看明白,它与配置文件有关,我们都知道级连的东西要定义一个级连的顺序,我把这个顺序定义在了web.config里:

 

1 
2     <appSettings>
3         <add key="Ddl_Keys_Address" value="Ddl_City,Ddl_Suburb,Ddl_Street"/>
4         <add key="Ddl_City" value="Chinasoft.Models.Cities"/>
5         <add key="Ddl_Suburb" value="Chinasoft.Models.Suburbs"/>
6         <add key="Ddl_Street" value="Chinasoft.Models.Streets"/>
7     </appSettings>

 

 

进一步看为Form获取数据的代码会更明白一点,以下是后面例子(本系列第三篇)中要调用的为View提供数据的代码(DdlSampleFormModel的定义稍后贴出),因为是Demo,所以用了些俗称硬编码的东东,嘿嘿:

 

其中定义如下接口:

 

1 
2     public interface IDdlSampleRepository
3     {
4         DdlSampleFormModel GetInfo();
5     }

 

 

然后具体类:

 1 
 2     public class DdlSampleRepository : IDdlSampleRepository
 3     {
 4         public DdlSampleFormModel GetInfo()
 5         {
 6             DdlSampleFormModel model = new DdlSampleFormModel();
 7             model.Data = new AddressDetailModel(0000"Other info");
 8 
 9             var ddlKeyConfig = "Ddl_Keys_Address";
10 
11             var countrySelectList = new Countries().GetSelectList(model.Data.Country);
12             model.Countries = DdlFormModel.CreateInstance(
13                 ddlKeyConfig
14                 , "County"
15                 , countrySelectList
16                 , "City,Suburb,Street"
17                 , "Ddl_City");
18 
19             model.Cities = DdlFormModel.CreateInstance(
20                 ddlKeyConfig
21                 , "City"
22                 , new Cities()
23                 , model.Data.Country
24                 , model.Data.City
25                 , "Suburb,Street"
26                 , "Ddl_Suburb");
27 
28             model.Suburbs = DdlFormModel.CreateInstance(
29                 ddlKeyConfig
30                 , "Suburb"
31                 , new Suburbs()
32                 , model.Data.City
33                 , model.Data.Suburb
34                 , "Street"
35                 , "Ddl_Street");
36 
37             model.Streets = DdlFormModel.CreateInstance(
38                 ddlKeyConfig
39                 , "Street"
40                 , new Streets()
41                 , model.Data.Suburb
42                 , model.Data.Street);
43 
44             return model;
45         }
46     }

其中的var ddlKeyConfig = "Ddl_Keys_Address";对应配置文件中的第一个配置的key,它定义了层次顺序,同时也可以看出来DdlFormModel的第三个CreateInstance方法重载是用于顶级下拉框的(这里用于国家),第一个CreateInstance方法重载是用于既有父又有子的下拉框的(这里是城市、区县),第二个CreateInstance方法重载是用于底层下拉框的(这里是Street)。

配置文件里的第二、三、四个配置,是用于利用反射来获取下拉框后续数据的,简单说就是当国家变了时候用Ajax来更新城市、区县、街道时候用的。具体在第三篇里讨论。

 

下面是DdlSampleFormModel的代码(它用于Views\DdlSample\Index.aspx提供数据,在第三篇可以看到Views\DdlSample\Index.aspx):

1 
2     public class DdlSampleFormModel
3     {
4         public AddressDetailModel Data { getset; }
5         public DdlFormModel Countries { getset; }
6         public DdlFormModel Cities { getset; }
7         public DdlFormModel Suburbs { getset; }
8         public DdlFormModel Streets { getset; }
9     }

 

 

后四个参数类型在本文的开始已经贴过了,是为下拉框用户控件提供的数据。第一个参数Data当然是对地址的一个封装,代码如下:

 1 
 2     public class AddressDetailModel
 3     {
 4         public int Country { getset; }
 5         public int City { getset; }
 6         public int Suburb { getset; }
 7         public int Street { getset; }
 8         public string OtherInfo { getset; }
 9 
10         public AddressDetailModel()
11         {
12         }
13         public AddressDetailModel(int country, int city, int suburb, int street, string otherInfo)
14         {
15             Country = country;
16             City = city;
17             Suburb = suburb;
18             Street = street;
19             OtherInfo = otherInfo;
20         }
21     }

 

题目虽为FormModel们,但是光看Model不容易看明白,所以把有关上下文的代码都贴了上来,以帮助理解。细心的人应该会注意到DdlFormModel类里一定也用到Javascript了吧,JS代码会在第三篇里贴出。

 

忘了有一个工具类了,它是在HasParentBase和SelectListProviderBase中使用到的,一共2个功能,第一个功能是根据基础数据生成SelectList,第二个是添加空选项:

 

 1 
 2     public static class RepositoryHelper
 3     {
 4         public static SelectList GetSelectList
 5             (IEnumerable<KeyValuePair<stringstring>> values, int? selectedValue)
 6         {
 7             SelectList list;
 8             if (selectedValue.HasValue)
 9             {
10                 list = new SelectList(values, "Key""Value", selectedValue);
11             }
12             else
13             {
14                 list = new SelectList(values, "Key""Value");
15             }
16             return list;
17         }
18 
19         public static void AddEmpty(List<KeyValuePair<stringstring>> list)
20         {
21             list.Insert(0new KeyValuePair<stringstring>(""""));
22         }
23     }

 

 

欢迎扔鸡蛋!

posted on 2010-07-10 17:15  灰灰狼  阅读(2091)  评论(0编辑  收藏  举报