首页 > 关于一个无限分类的多选,单选相关的控件

关于一个无限分类的多选,单选相关的控件

最近在一个项目中需要用到无限分类的平铺多选,单选这些功能,查了一些资料,结果大都是一些用IFrame这样的东西做的,虽然用起来直观,但本人更喜欢集成控件形式的,于是抽了一些时间做了一个.思路是利用控件+JS+不同的无限分类表,支持一页多控件,支持不同的无限分类表.效果图如下:

当这些父类被选择时,子类都被选择.当这些父类取消选择时,其下所有子类都被取消选择.

代码如下:

控件behind代码CS:

 

ContractedBlock.gifExpandedBlockStart.gifMultiSelectItems.ascx.cs
  1 using System;

  2 using System.Collections;

  3 using System.Collections.Generic;

  4 using System.Configuration;

  5 using System.Data;

  6 using System.Linq;

  7 using System.Web;

  8 using System.Web.Security;

  9 using System.Web.UI;

 10 using System.Web.UI.HtmlControls;

 11 using System.Web.UI.WebControls;

 12 using System.Web.UI.WebControls.WebParts;

 13 using System.Xml.Linq;

 14 using Models;

 15 

 16 public partial class MultiSelectItems : System.Web.UI.UserControl

 17 {

 18     public List<Groups> groupList { getset; }   

 19 

 20     public string hasSel

 21     {

 22         set

 23         {

 24             if (!string.IsNullOrEmpty(value))

 25             {

 26                 //绑定已选数据                    

 27                 value = value.Trim(',');

 28                 string[] hasSels = value.Split(',');

 29                 foreach (string s in hasSels)

 30                 {

 31                     scriptStr += "document.getElementById('checkItems" + tableName + s + "').checked=true; ";

 32                     scriptStr += "checkProperty('" + tableName + "'," + s + ",'" + controlName + "'); ";

 33                 }

 34                 scriptStr += "document.getElementById('checkeds" + tableName + "').value='" + value + ",'; ";

 35             }

 36         }

 37     }

 38     public string tableName { getset; }

 39     public string controlName { getset; }

 40     public string scriptStr = string.Empty;

 41     public string multiItemsInnerHtml = string.Empty;

 42     protected void Page_Load(object sender, EventArgs e)

 43     {

 44         //此控件配合JS使用

 45         //使用方法:

 46         //在页面顶部加载此控件:<%@ Register Src="~/controls/MultiSelectItems.ascx" TagName="mi" TagPrefix="MultiSelectItem" %>

 47         //在head中加载相应JS:

 48         //在页面相关位置放置此控件:ID不受限制

 49         //配置一些属性

 50         //miArea.st = SysTable.AreaGroups;//加载哪个表          

 51         //miArea.controlName = "checkedsAreaGroups";//要获取值的text控件名

 52         //miArea.BindData();//绑定初始数据

 53         //如果是修改选项,可以设置已有选项:miArea.hasSel = sm.Area_Items;

 54         //获取该控件的值,这个名称就是刚刚配置的名称:Request.Form["checkedsAreaGroups"]

 55     }

 56     /// 

 57     /// 绑定初始的多选表单数据,这些数据都是未被选择的,如果要选择数据,请设置该对象相关实例的hasSel属性

 58     /// 


 59     public void BindData()

 60     {

 61         string brStr = string.Empty;

 62         string clickStr = string.Empty;

 63         string tpGroupName = string.Empty;

 64         string tpBox = string.Empty;

 65         if (groupList != null)

 66         {

 67             foreach (Groups gp in groupList)

 68             {

 69                 brStr = string.Empty;               

 70                 clickStr = "checkAllSubProperty('" + tableName + "','" + gp.GroupId + "','" + controlName + "')" ;

 71                 tpBox = "" + tableName + "' id='checkItems" + tableName + gp.GroupId + "' value='" + gp.ParentStr + gp.GroupId + "' οnclick="" + clickStr + "" /> ";

 72                 if (gp.Route == 1) {

 73                     tpGroupName = gp.GroupName.Substring(1);

 74                 }

 75                 else if (gp.Route == 2)

 76                 {

 77                     tpGroupName = gp.GroupName.Substring(1);                   

 78                 }

 79                 else {

 80                     tpGroupName = gp.GroupName.Substring(gp.Route - 1);                   

 81                 }

 82 

 83 

 84                 if (gp.Route == 1)

 85                 {

 86                     brStr = "";

 87                     multiItemsInnerHtml += brStr + tpBox + "" + tpGroupName + "
";

 88                 }

 89                 else

 90                 {

 91                     if (groupList.Where(c => c.ParentId == gp.GroupId).Count() > 0)

 92                     {

 93                         brStr = "";

 94                         multiItemsInnerHtml += brStr + tpBox + "" + tpGroupName + "";

 95                     }

 96                     else

 97                     {

 98                         multiItemsInnerHtml +=  tpBox + tpGroupName;

 99                     }                    

100                 }

101                 multiItemsInnerHtml += "  ";

102                 multiItemsInnerHtml += brStr;

103             }

104         }

105     }

106 }

 

html代码很简单:

 

ContractedBlock.gifExpandedBlockStart.gifMultiSelectItems.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MultiSelectItems.ascx.cs" Inherits="MultiSelectItems" %>

<div id="MultiItems<%=tableName%>"><%=multiItemsInnerHtml%>div>

<input type="hidden" name="<%=controlName%>" id="<%=controlName%>" value="" />

<script language="javascript" type="text/javascript">

<%=scriptStr%>

script>

 

接下来是相关的JS,注意,不论一个页面调用几次这个控件,此JS只加载一次

 

ContractedBlock.gifExpandedBlockStart.gifMultiSelectItems.js
    function checkAllSubProperty(tableName,groupid,checkedsControlName){

        
var checkedControl = document.getElementById("checkItems" + tableName + groupid);

        
var items = document.getElementsByName("checkItems" + tableName);

        
var checkeds = document.getElementById(checkedsControlName);

        
if(checkedControl.checked){

            checkeds.value 
+= groupid + ',';

        }
else{

            checkeds.value 
= checkeds.value.replace(groupid + ",","");

        }

        
for(var i=0;i<items.length;i++){

            
if(items.item(i).value.indexOf(',' + groupid + ','> -1){

                
var insertStr = items.item(i).value.substring(items.item(i).value.lastIndexOf(','+ 1,items.item(i).value.length) + ',';

                
if(checkedControl.checked){

                    items.item(i).checked 
= true;       

                    
if(checkeds.value.indexOf(insertStr) < 0){

                        checkeds.value 
+= insertStr;

                    }

                }
else{

                    items.item(i).checked 
= false

                    checkeds.value 
= checkeds.value.replace(insertStr,"");

                }

            }

        }        

    }

 

因为是基于.net 3.5的Linq做的控件,所以,此控件必须运行在装有3.5类库的机器上,而且,因为无限分类的数据库结构大家都清楚.是这样的:

稍微解释一下各字段含义:

GroupId:这是分类的主ID,自动增加,主键.

GroupName:这是分类的名字.

ParentId:这是父类的ID,

ParentStr:这是从根类--->父类---->父类....--->本类的父类的路径,以0开始,以,结束,例如0,2,10,22,这从算法上讲叫静态冗余字段,用来快速查找某个类的所有子类.例如要查找GroupId为2的所有子类,可以这样写语句:select top xx * from 表名 where ParentStr like '%,2,%',是不是比一般的遍历要快很多?

Route:这是指示该类的路径深度,如果是根类,则为1,如果是1级子类,则为2,依此类推,此字段主要用于快速查找某一级别的所有子类.

至于这个无限分类的维护,大家可以各显其能去优化.目前我的维护是采用缓存+List<>+ORM

 

 我写的东西大都是日常工作中用得比较多的,而且,相对来说,我会比较偷懒,例如,减少计算,减少数据库访问等.而且,本人不喜欢一个大括号里有很多条语句的代码方式.这样的代码比较难维护.如果我看到一个if或者while后接了一个大括号,然后整屏都看不到它的结束符.我会BS这段代码的作者.

 

 

f人要

转载于:https://www.cnblogs.com/CoreCaiNiao/archive/2009/12/01/1614665.html

更多相关:

  • IHostingEnviroment 获取环境相关洗洗 IsDevelopment()、IsStaging()、IsProduction() 分别为:开发、准生产、生产环境 IsEnviroment("Uat") 自定义环境,比如自定义Uat环境 新建: appsettings.Uat.json文件 {"Enviroment":...

  • 七. DockPanel DockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列,这些对象位于 Children 属性中。停靠面板其实就是在WinForm类似于Dock属性的元 素。DockPanel会对每个子元素进行排序,并停靠在面板的一侧,多个停靠在同侧的元素则按顺序排序。     如果将 LastChild...

  • 该链接有导入,导出源码,我的代码有下链接改写,完善而成的, http://www.cnblogs.com/colder/p/3611906.html using System;using System.Collections.Generic;using System.Linq;using System.Web;using System...

  • 转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 对于SharePoint中已经是Record的Item,我们想要修改他的属性,这在UI界面是无法完成的: 这时需要通过Records.BypassLocks API来完成。设计一个tool,利用Records.BypassLocks...

  • C# async await 学习笔记1(http://www.cnblogs.com/siso/p/3691059.html)  提到了ThreadId是一样的,突然想到在WinForm中,非UI线程是无法直接更新UI线程上的控件的问题。 于是做了如下测试: using System; using System.Collectio...

  • 不BB写在自己博客园看的舒服     RelativeLayout布局 android:layout_marginTop="25dip" //顶部距离 android:gravity="left" //空间布局位置 android:layout_marginLeft="15dip //距离左边距 // 相对于给定ID控件 andro...

  • top.geometry()设定窗口的初始大小 scale.set()设定滑块的初始值 scale.get()获取滑块变化的值 控件通过回调函数与其他控件进行通信(Label控件中的文本会受到Scale控件上操作的影响) 转载于:https://www.cnblogs.com/TmHm/p/9949947.html...

  • 在一些控件里的keydown方法,没有办法捕获所有的按键消息 比如自己写一个窗体控件库,继承了UserControl 但是没有办法捕获一些键,比如方向键等 所以必须重载 processDialogkey 方法 processDialogkey 的描述 在msdn中是这样的   在消息预处理过程中调用此方法,以处理对话框字符,比如 Ta...

  • 六 PetShop之表示层设计 表示层(Presentation Layer)的设计可以给系统客户最直接的体验和最十足的信心。正如人与人的相交相识一样,初次见面的感觉总是永难忘怀的。一件交付给客户使用的产品,如果在用户界面(User Interface,UI)上缺乏吸引人的特色,界面不友好,操作不够体贴,即使这件产品性能非常优异,架...

  • ASP.NET页生命周期的定义,有以下8个方面:页请求,开始,页初始化,页加载,验证,回发事件,呈现,卸载。 ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤。这些步骤包括初始化、实例化控件、还原和维护状态、运行事件处理程序代码以及进行呈现。了解页的生命周期非常重要,这样就能在合适的生命周期阶段编写代...

  • #include #include #include #include #include #include #include

  • 题目:表示数值的字符串 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"0123"及"-1E-16"都表示数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。 解题: 数值错误的形式有多种多样,但是正确的...

  • 加法伺候  //超过20位数值相加---------------------------------------- function bigNumAdd(a, b) {if (!(typeof a === "string" && typeof b === "string")) return console.log("传入参数必...

  • 业务场景: 从中文字句中匹配出指定的中文子字符串 .这样的情况我在工作中遇到非常多, 特梳理总结如下. 难点: 处理GBK和utf8之类的字符编码, 同时正则匹配Pattern中包含汉字,要汉字正常发挥作用,必须非常谨慎.推荐最好统一为utf8编码,如果不是这种最优情况,也有酌情处理. 往往一个具有普适性的正则表达式会简化程...

  • 简单record 一下 #include // 'struct sockaddr_in' #include #include // 'struct ifreq' and 'struct if_nameindex' #include #inc...