zoukankan      html  css  js  c++  java
  • Asp.net WebForm DropDownList 无限极联动(不需要写C#代码,不需要写JS,只是配置属性)

    1.承上启下

    2.新增的功能

    3.源码

    4.小结

    承上启下(一些废话,与今天同事的一点对话。小菜:26岁。 同事:30岁。)

    上一篇 Asp.net Webform 数据源绑定控件的扩展(懒人的办法):DropDownList

    中提到了根据界面属性来动态绑定 DropDownList ,并跟本公司的同事讨论了下,同事的意思是没有必要写控件,原因如下:1. 没有时间写。 2. 后台取读取数据挺方便的(通过硬编码的方式)。一下是小菜跟公司同事的一点点对话,原文如下:

    小菜说:现在写了以后一劳永逸。(点评:小菜只是想把封装一下控件的好处阐明一下,希望同事们一起向这方面努力!公司有自己的易用快速开发框架!因为公司的开发环境现在是,硬编码满天飞,没有一个统一的标准!)

    同事说:没必要写控件。(点评:小菜很迷惑为什么没有必要,小菜很困惑。)

    小菜:为什么没必要,写好了控件。以后业务变更都不需要重新编译,现在每次都要在 Page_Load 里面加载数据,手写代码,如果一旦数据改变,使用 DropDownList 的源码都可能需要更改!

    (点评:小菜提出自己的困惑,并通过阐明自己写扩展控件的原因)

    同事:不是每次都在 Page_Load 里面加载的?(点评:我想我说的是扩展控件的利弊,不知道为什么同事会提出这个问题?以此做突破口,打败我?)

    小菜:不再Page_Load里面加载你数据怎么来?(点评:小菜想了想,感觉无论什么框架,数据在DB也好在文件中也好,肯定得加载到控件端的!小菜接招了!)

    同事:你做DropDownList联动的时候,一开始怎么会从DropDownList里面读取呢?(点评:提出假设,同事说的不错。不过小菜想说,我做控件的初衷就是屏蔽代码中的不可控性,提高代码扩展,修改的性能,这种的确是不再Page_Load中加载,但是... ... 大家都明白... ...这一局同事完胜我了,成功了抓住了我语句中的漏洞,我输了!)

    小菜:这个我知道但是,这些也要写在cs文件里面啊,也要人为的去写逻辑啊!()(点评:提出者中做法也是有小菜初衷所要解决的问题。)

    同事:没必要,你以为开发控件那么容易,根本没时间。(点评:另一个理由,貌似又要回到问题的原点。)

    小菜: ... ...(点评:小菜认输了,沉默了... ...)

    总结:一些题外话。小菜是个真心喜欢技术的人,对于时间问题小菜想说,每个人都是24个小时,为什么我有时间你没有呢?小菜每天都是1-2点睡觉,7点上班的,下班后回家吃饭,开电脑,然后就是博客园。写代码。睡觉,小菜的技术就这样不是什么高深的东西,也写不出大牛的水平(例如:@Fish Li,我很喜欢他。他的技术都是一针见血的。)但是小菜今年只有26岁,毕业两年,北京工作一年,小菜还很年轻,小菜会一直努力。至于现在我们公司的开发环境来说,我大三的水平时候就能胜任现在的开发任务(就当我是吹牛吧,别拍砖!)。小菜没有浑浑噩噩,也没有放弃对编程的追求。现实的因素左右过我,但是不能决定我。我会一直努力... ... 对于那些只把技术当做混饭吃的工具的人,我不能说你什么!每个人都有自己的选择和处事方法,我只是希望那些真正耐得住寂寞的喜欢编程的人,多交流,小菜向你们多学习。通过自己的志趣,跟自己的生活家庭带来更好的生活。技术,编程,学习不是生活,但也不能这么浑浑噩噩吧?

    新增加的功能

    对原有功能的扩展,增加了4个新的属性,以此来实现DropDownList的联动功能,支持无限极联动。使用IE 9,Chrome测试过没有问题。

    视图例子:

    只是做了一个4级联动小例子,不依赖数据库,只依赖我写的数据库操作类,你也可以把数据库操作类自己重写,来实现。

    源代码

    FindControl Extends
     1     public static Control FindAllControl(this System.Web.UI.Control control, string controlID)
     2         {
     3             return FindControlForeach(control, controlID);
     4         }
     5 
     6         private static Control FindControlForeach(Control control, string controlID)
     7         {
     8             Control findResult = control.FindControl(controlID);
     9             if (findResult == null)
    10             {
    11                 foreach (Control childControl in control.Controls)
    12                 {
    13                     findResult = FindControlForeach(childControl, controlID);
    14                     if (findResult != null) break;
    15                 }
    16             }
    17             return findResult;
    18         }

    由于新增了联动功能,所以需要后台自动识别联动控件的ID所以扩展了 Control 的FindControl 功能。

    一下是Page.aspx需要的属性设计(刚才吃着吃着饭,想起来没加!汗!)

    Aspx Code
     1 <div>
     2     
     3         <bsp:DropDownList ID="DropDownList1" runat="server" ConnectionName="Platform" 
     4             DataTextField="ObjectName" DataValueField="PKey" DefaultText="-全部-" 
     5             RelevanceID="DropDownList2" SortName="ObjectOrderBy" TableName="RBAC_View" 
     6             Where="ParentKey is null">
     7         </bsp:DropDownList>
     8         <bsp:DropDownList ID="DropDownList2" runat="server" ConnectionName="Platform" 
     9             DataTextField="ObjectName" DataValueField="UserPKey" DefaultText="-全部-" 
    10             RelevanceID="DropDownList3" RelevanceName="ParentKey" SortName="ObjectOrderBy" 
    11             TableName="RBAC_View" Where="PKey=null">
    12         </bsp:DropDownList>
    13         <bsp:DropDownList ID="DropDownList3" runat="server" ConnectionName="Platform" 
    14             DataTextField="UserName" DataValueField="PKey" DefaultText="-请选择-" 
    15             RelevanceName="PKey" TableName="RBAC_Users" Where="Pkey is null" 
    16             RelevanceID="DropDownList4">
    17         </bsp:DropDownList>
    18         <bsp:DropDownList ID="DropDownList4" runat="server" ConnectionName="Platform" 
    19             DataTextField="ObjectName" DataValueField="PKey" DefaultText="-请选择-" 
    20             RelevanceName="UserPkey" SortName="ObjectOrderBy" TableName="RBAC_View" 
    21             Where="1=2">
    22         </bsp:DropDownList>
    23     
    24     </div>
    DropDownList
      1     [DefaultProperty("Text")]
      2     [ToolboxData("<{0}:DropDownList runat=server></{0}:DropDownList>")]
      3     public class DropDownList : System.Web.UI.WebControls.DropDownList
      4     {
      5         #region Extends Attributes
      6 
      7         private Database DataAccess;
      8 
      9         /// <summary>
     10         /// 摘要: 操作数据库的 TableName
     11         /// </summary>
     12         [Bindable(true)]
     13         [Category("Extends")]
     14         [DefaultValue("")]
     15         [Localizable(true)]
     16         public string TableName
     17         {
     18             get
     19             {
     20                 String s = (String)ViewState["TableName"];
     21                 return ((s == null) ? String.Empty : s);
     22             }
     23 
     24             set
     25             {
     26                 ViewState["TableName"] = value;
     27             }
     28         }
     29         /// <summary>
     30         /// 摘要: 操作数据库的 ConnectionName
     31         /// </summary>
     32         [Bindable(true)]
     33         [Category("Extends")]
     34         [DefaultValue("")]
     35         [Localizable(true)]
     36         public string ConnectionName
     37         {
     38             get
     39             {
     40                 String s = (String)ViewState["ConnectionName"];
     41                 return ((s == null) ? String.Empty : s);
     42             }
     43 
     44             set
     45             {
     46                 ViewState["ConnectionName"] = value;
     47             }
     48         }
     49         /// <summary>
     50         /// 摘要: DropDownList 默认选项,空则为默认选项
     51         /// </summary>
     52         [Bindable(true)]
     53         [Category("Extends")]
     54         [DefaultValue("")]
     55         [Localizable(true)]
     56         public string DefaultText
     57         {
     58             get
     59             {
     60                 String s = (String)ViewState["DefaultText"];
     61                 return ((s == null) ? String.Empty : s);
     62             }
     63 
     64             set
     65             {
     66                 ViewState["DefaultText"] = value;
     67             }
     68         }
     69         /// <summary>
     70         /// 摘要: 操作数据库的表的 WHERE 条件
     71         /// </summary>
     72         [Bindable(true)]
     73         [Category("Extends")]
     74         [DefaultValue("")]
     75         [Localizable(true)]
     76         public string Where
     77         {
     78             get
     79             {
     80                 String s = (String)ViewState["Where"];
     81                 return ((s == null) ? "1=1" : s);
     82             }
     83 
     84             set
     85             {
     86                 ViewState["Where"] = value;
     87             }
     88         }
     89         /// <summary>
     90         /// 摘要: 排序字段,空则为 DataTextField
     91         /// </summary>
     92         [Bindable(true)]
     93         [Category("Extends")]
     94         [DefaultValue("")]
     95         [Localizable(true)]
     96         public string SortName
     97         {
     98             get
     99             {
    100                 String s = (String)ViewState["SortName"];
    101                 return ((s == null) ? this.DataTextField : s);
    102             }
    103 
    104             set
    105             {
    106                 ViewState["SortName"] = value;
    107             }
    108         }
    109         /// <summary>
    110         /// 摘要: 以此 DataValueFiled 为主的联动 DropDownList.ID
    111         /// </summary>
    112         [Bindable(true)]
    113         [Category("Extends")]
    114         [DefaultValue("")]
    115         [Localizable(true)]
    116         public string RelevanceID
    117         {
    118             get
    119             {
    120                 String s = (String)ViewState["RelevanceID"];
    121                 return ((s == null) ? string.Empty : s);
    122             }
    123             set
    124             {
    125                 ViewState["RelevanceID"] = value; if (!string.IsNullOrEmpty(value)) { this.AutoPostBack = true; }
    126             }
    127         }
    128         /// <summary>
    129         /// 摘要: 接收父级 DropDownList 的值的对应字段
    130         /// </summary>
    131         [Bindable(true)]
    132         [Category("Extends")]
    133         [DefaultValue("")]
    134         [Localizable(true)]
    135         public string RelevanceName
    136         {
    137             get
    138             {
    139                 String s = (String)ViewState["RelevanceName"];
    140                 return ((s == null) ? string.Empty : s);
    141             }
    142             set
    143             {
    144                 ViewState["RelevanceName"] = value;
    145             }
    146         }
    147         /// <summary>
    148         /// 摘要: 是否联动父集
    149         /// </summary>
    150         [Bindable(true)]
    151         [Category("Extends")]
    152         [DefaultValue("")]
    153         [Localizable(true)]
    154         public bool IsRelevanceChild
    155         {
    156             get
    157             {
    158                 String s = (String)ViewState["RelevanceName"];
    159                 return !(s == null);
    160             }
    161         }
    162         /// <summary>
    163         /// 摘要: 是否联动子集
    164         /// </summary>
    165         [Bindable(true)]
    166         [Category("Extends")]
    167         [DefaultValue("")]
    168         [Localizable(true)]
    169         public bool IsRelevanceFather
    170         {
    171             get
    172             {
    173                 String s = (String)ViewState["RelevanceID"];
    174                 return !(s == null);
    175             }
    176         }
    177 
    178         #endregion
    179 
    180         #region Override Method
    181 
    182         protected override void OnDataBinding(EventArgs e)
    183         {
    184             LoadData();
    185             base.OnDataBinding(e);
    186         }
    187 
    188         protected override void OnDataBound(EventArgs e)
    189         {
    190             base.OnDataBound(e);
    191             InsertDefaultText();
    192             RelevanceOther();
    193            
    194         }
    195 
    196         protected override void OnPagePreLoad(object sender, EventArgs e)
    197         {
    198             if (!Page.IsPostBack)
    199                 this.DataBind();
    200             base.OnPagePreLoad(sender, e);
    201         }
    202 
    203         protected override void OnSelectedIndexChanged(EventArgs e)
    204         {
    205             RelevanceOther();
    206             base.OnSelectedIndexChanged(e);
    207         }
    208 
    209         #endregion
    210 
    211         #region Private Method
    212 
    213         private void LoadData()
    214         {
    215             if (!string.IsNullOrEmpty(DataTextField) && !string.IsNullOrEmpty(DataTextField) && !string.IsNullOrEmpty(TableName))
    216             {
    217                 DataAccess = string.IsNullOrEmpty(ConnectionName) ?
    218                     (this.Page as Binarysoft.Library.Web.UI.Page).DataAccess :
    219                     DatabaseFactory.CreateDatabase(ConnectionName);
    220                 this.DataSource = DataAccess.ExecuteDataTable(string.Format("SELECT {0},{1} FROM {2} WHERE {3} ORDER BY {4}", DataTextField, DataValueField, TableName, Where, SortName));
    221             }
    222         }
    223 
    224         private void InsertDefaultText()
    225         {
    226             if (!string.IsNullOrEmpty(DefaultText))
    227                 this.Items.Insert(0, new ListItem(DefaultText, string.Empty));
    228         }
    229 
    230         private void RelevanceOther()
    231         {          
    232             if (IsRelevanceFather)
    233             {
    234                 DropDownList findedControl = (this.Page.Form.FindAllControl(RelevanceID) as DropDownList);
    235                 if (findedControl != null)
    236                 {
    237                     findedControl.Where = string.Format("{0} = '{1}'", findedControl.RelevanceName, this.SelectedValue);
    238                     findedControl.DataBind();
    239                 }
    240             }
    241         }
    242 
    243         #endregion
    244     }

    小结

    这个控件,没有支持Ajax是我唯一感觉不足的地方。原因是,小菜还没最终决定,如何实现Ajax的功能,以下是小菜的一点想法,实现ajax功能:

    1.使用Jquery,但是感觉前台一堆代码要手动维护。

    2.使用系统自带的接口,代码有些冗余。

    3.使用Anthem的接口,小菜还没有完全弄明白它的原理。

    希望,给位大牛给点意见!希望大家同路人多交流,道不同的就不相为谋好了!欢迎拍砖。

    博客不易,转载请注明出处。Binarysoft.
  • 相关阅读:
    Cg学习
    Unity URP
    unity官方案例水效果解析
    Unity使用Xlua框架热更
    隐私政策以及用户协议
    iOS App 从点击到启动
    iOS编程中throttle那些事
    Homebrew安装
    ios 开发证书 appids 描述文件关系
    学习网站
  • 原文地址:https://www.cnblogs.com/BinaryBoy/p/2964865.html
Copyright © 2011-2022 走看看