Asp.net >> CheckBoxList控件

本篇主要介绍asp.net控件CheckBoxList,会分好几个DEMO来实现。其中会出现几个DLL对象,可从下面地址下载:

http://www.cnblogs.com/insus/articles/1654653.html

http://www.cnblogs.com/insus/articles/1622884.html

 

从数据库取出数据绑定至CheckBoxList控件,在取出数据之前,得在SQL数据库准备一些数据,创建表[DevCodes],插入数据与获取数据存储过程usp_DevCodes_GetAll:

View Code
CREATE TABLE [dbo].[DevCodes]
(
    
[DC_nbr] [int] IDENTITY(1,1PRIMARY KEY NOT NULL,
    
[CodeName] [nvarchar](50NOT NULL,
)

GO

INSERT INTO [dbo].[DevCodes] ([CodeName]VALUES
(
'Assembly'),('C#'),('C/C++'),('CSS'),('HTML'),('Java'),('JScript'),('Delphi(Pascal)'),('Perl'),('PHP'),('Python'),('SQL'),('VB'),('VB.NET'),('VBScript'),('XML')

GO

CREATE PROCEDURE [dbo].[usp_DevCodes_GetAll]
AS
SELECT [DC_nbr],[CodeName] FROM [dbo].[Devcodes]
GO

 

DevCodes类别:

DevCodes
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;

/// <summary>
/// Summary description for DevCodes
/// </summary>
namespace Insus.NET
{
    
public class DevCodes
    {
        BusinessBase objBusinessBase 
= new BusinessBase();

        
public DevCodes()
        {
            
//
            
// TODO: Add constructor logic here
            
//
        }

        
public DataTable GetDevCodes()
        {
            
return objBusinessBase.GetDataToDataSet("usp_DevCodes_GetAll").Tables[0];
        }
    }
}

 

.aspx:

View Code
 <asp:ScriptManager ID="ScriptManager1" runat="server">
    
</asp:ScriptManager>
    
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
        
<ContentTemplate>
            
<div>
                Development Code:
                
<br />
                
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatColumns="4" RepeatDirection="Horizontal">
                
</asp:CheckBoxList>               
            
</div>
        
</ContentTemplate>
    
</asp:UpdatePanel>

 

.aspx.cs:

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Insus.NET;

public partial class Default2 : System.Web.UI.Page
{
    DevCodes objDevCodes 
= new DevCodes();

    
protected void Page_Load(object sender, EventArgs e)
    {
        
if (!IsPostBack)
        {
            Data_Binding();
        }
    }

    
private void Data_Binding()
    {
        
//常规写法
        this.CheckBoxList1.DataSource = objDevCodes.GetDevCodes();
        
this.CheckBoxList1.DataTextField = "CodeName";
        
this.CheckBoxList1.DataValueField = "DC_nbr";
        
this.CheckBoxList1.DataBind();
    }
}

 

运行时,可以预览到结果:

 

接下来,是重构,因为一个专案之中,CheckBoxList会有多处地方出现,参考下图常规的写法,非常繁杂,重构中会使用到CheckBoxListUtility对象,去简化CheckBoxList的写法,重构之后,把常规写法的代码注释掉。

 

 Demo1,把选择的选择显示出来,Insus.NET会在.aspx页面放置一个Button和另外一个CheckBoxList去显示选择的结果。

在SQL中写一个存储过程usp_DevCodes_GetByNbr:

View Code
CREATE PROCEDURE [dbo].[usp_DevCodes_GetByNbr] 
(
    
@nbr NVARCHAR(100)
)
AS
DECLARE @Params NVARCHAR(100= REPLACE(@nbr',',''',''')
EXECUTE('SELECT [DC_nbr],[CodeName] FROM [dbo].[Devcodes] WHERE [DC_nbr] IN (''' + @Params + ''')')

 

在DevCodes类别添加一个方法GetDevCodesByNbr():

View Code
 public DataTable GetDevCodesByNbr(string nbr)
        {
            Parameter[] parameter 
= {
                                      
new Parameter("@nbr",SqlDbType.NVarChar,100,nbr)
                                  };
            
return objBusinessBase.GetDataToDataSet("usp_DevCodes_GetByNbr",parameter).Tables[0];
        }

 

 在.aspx页面中,添加如下html:

View Code
 <br />
                
<asp:Button ID="Button1" runat="server" Text="Select" OnClick="Button1_Click" />
                
<br />
                Select development Code:
                
<br />
                
<asp:CheckBoxList ID="CheckBoxList2" runat="server" RepeatColumns="4" RepeatDirection="Horizontal">
                
</asp:CheckBoxList>

 

在.aspx.cs写Button1_Click事件,下面代码中,你会看到有一个函数GetCheckBoxListSelectedValue(),这个函数最好写在一个公共类别中,这样子整个专案中都可以调用这个函数: 

View Code
  protected void Button1_Click(object sender, EventArgs e)
    {
        
string nbr = GetCheckBoxListSelectedValue(this.CheckBoxList1);
        objCbl.CheckBoxListParse(
this.CheckBoxList2, objDevCodes.GetDevCodesByNbr(nbr), "CodeName""DC_nbr");
    }

    
//处理选择的值
    private string GetCheckBoxListSelectedValue(CheckBoxList checkBoxList)
    {
        
string selectedValue = string.Empty;
        
foreach (ListItem li in checkBoxList.Items)
        {
            
if (li.Selected)
            {
                selectedValue 
= selectedValue + "," + li.Value;
            }
        }

        
if (selectedValue.Length > 0)
        {
            selectedValue 
= selectedValue.Substring(1);
        }

        
return selectedValue;
    }

 

 页面在run时,选择一些选项之后,得到的结果:

 

Demo2,放置一个CheckBox控件,实现全选功能,这个CheckBox设置属性AutoPostBack="true"和事件OnCheckedChanged ="CheckBox1_CheckedChanged" 。

View Code
  Development Code:
                
<br />
                Check all:
<asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="true" OnCheckedChanged ="CheckBox1_CheckedChanged" /><br />
                
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatColumns="4" RepeatDirection="Horizontal">
                
</asp:CheckBoxList>

 

在.aspx.cs写OnCheckedChanged的事件CheckBox1_CheckedChanged:

View Code
 protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
    {
        ChangedCheckBoxListSelectState(
this.CheckBox1, this.CheckBoxList1);
    }


    
private void ChangedCheckBoxListSelectState(CheckBox cb, CheckBoxList cbl)
    {
        
if (cb.Checked)
        {
            CheckedChanged(cbl, 
true);
        }
        
else
        {
            CheckedChanged(cbl, 
false);
        }
    }

    
private void CheckedChanged(CheckBoxList cbl, bool isSelected)
    {
        
foreach (ListItem li in cbl.Items)
        {
            li.Selected 
= isSelected;
        }
    }

 

运行时,选择这个全选的checkBox,显示效果如下:

 

 Demo3,这个部分,我们把用户选择的做永久保存,即是说保存至SQL数据库中。然后在页面显示时,再去读取数据库。这样子,我们在数据库中设计相关表与存储过程,参考下面SQL代码。

View Code
--创建一个表,存储用户选择的数据
CREATE TABLE MyProfile
(
    U_Name 
NVARCHAR(30UNIQUE NOT NULL ,
    MyCode 
NVARCHAR(100NULL
)
GO



--存储过程保存用户选择
CREATE PROCEDURE usp_MyProfile_IntOrUpd
(
    
@U_Name NVARCHAR(30),
    
@MyCode NVARCHAR(100)
)
AS
--保存之前首先判断是否已经曾经保存过
SELECT [U_Name],[MyCode] FROM [dbo].[MyProfile] WHERE [U_Name] = @U_Name

--如果是首次选择,把选择选项插入这个表中
IF @@ROWCOUNT <= 0 
    
INSERT INTO [dbo].[MyProfile] ([U_Name],[MyCode]VALUES (@U_Name,@MyCode)
--非首次,做更新动作。
ELSE 
    
UPDATE [dbo].[MyProfile] SET [MyCode] = @MyCode  WHERE [U_Name] = @U_Name
GO



--创建一个存储过程,Get By user选择的数据。    
CREATE PROCEDURE usp_MyProfile_GetByUser
(
    
@U_Name NVARCHAR(30)
)
AS
    
SELECT [MyCode] FROM [dbo].[MyProfile] WHERE [U_Name] = @U_Name
GO

 

 修改DevCodes类别,添加一个方法InsertOrUpdate(xxx)与函数GetMyCodeByUser(xxx):

View Code
 //保存用户选择的选项,插入或是更新
        public void InsertOrUpdate(string uname, string mycode)
        {
            Parameter[] parameter 
= { 
                                      
new Parameter("@U_Name",SqlDbType.NVarChar,30,uname),
                                      
new Parameter("@MyCode",SqlDbType.NVarChar,100,mycode)
                                    };
            objBusinessBase.ExecuteProcedure(
"usp_MyProfile_IntOrUpd", parameter);
        }

        
//获取用户保存的选择的数据
        public string GetMyCodeByUser(string uname)
        { 
              Parameter[] parameter 
= {
                                      
new Parameter("@U_Name",SqlDbType.NVarChar,30,uname)
                                  };
              
return Convert.ToString(objBusinessBase.ExecuteProcedureScalar("usp_MyProfile_GetByUser", parameter));
        }

 

继续修改选择Button1_Click事件:

 protected void Button1_Click(object sender, EventArgs e)
    {
        
string nbr = GetCheckBoxListSelectedValue(this.CheckBoxList1);
        
//objCbl.CheckBoxListParse(this.CheckBoxList2, objDevCodes.GetDevCodesByNbr(nbr), "CodeName", "DC_nbr");
        try
        {
           
//注意一下这个"Insus.NET",由于没有用户注册环境,如果有的话,应该取得当前用户ID   
            objDevCodes.InsertOrUpdate("Insus.NET", nbr);         
        }
        
catch (Exception ex)
        {
            InsusJsUtility objJs 
= new InsusJsUtility();
            objJs.JsAlert(ex.Message);
        }
    }

 

页面运行时,选择Dev code之后关触发铵钮事件,然后去数据库查看Myprofile表,可以看到保存的结果:

 

 接下来是新建另外一页Edit.aspx,把用户选择的选项从数据库取出来,并显示在编辑页面中,如下图:


 

新建一页Edit.aspx:

View Code
<body>
    
<form id="form1" runat="server">
    
<div>
        My Code:
        
<br />
        
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatColumns="4" RepeatDirection="Horizontal">
        
</asp:CheckBoxList>
    
</div>
    
</form>
</body>

 

 .Edit.aspx.cs:

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Insus.NET;

public partial class _Edit : System.Web.UI.Page
{
    DevCodes objDevCodes 
= new DevCodes();
    CheckBoxListUtility objCbl 
= new CheckBoxListUtility();
    
    
protected void Page_Load(object sender, EventArgs e)
    {
        
if (!IsPostBack)
        {
            Data_Binding();
        }
    }

    
private void Data_Binding()
    {
       
//从数据库取出用户选择的选项
        string myCode = objDevCodes.GetMyCodeByUser("Insus.NET");
        
//转为阵列
        string[] cde = myCode.Split(',');
        
//使用CheckBoxListUtility组件之上,留意方法重载,最后一个参数
        objCbl.CheckBoxListParse(this.CheckBoxList1, objDevCodes.GetDevCodes(), "CodeName""DC_nbr",cde);
    }   
}

 

下图解剖,把选择的值绑定至CheckBoxList控件上。

 

 

 Demo4,这段演示,把CheckBoxList嵌入至GridView中去,为了演示,Insus.NET在数据库中创建另一个表[Program],其中有一个字段是与上面一表[MyProfile]的[U_Name]关联,以及一个存储过程usp_Program_GetAll。

View Code
CREATE TABLE Program
(
    Program_nbr 
INT IDENTITY PRIMARY KEY NOT NULL,
     
NVARCHAR(50NOT NULL,
    U_Name 
NVARCHAR(30)
)
GO

INSERT INTO [dbo].[Program] ([Pgm_Name],[U_Name]VALUES ('Software Management System','Insus.NET')

GO

CREATE PROCEDURE usp_Program_GetAll
AS
SELECT [Program_nbr],[Pgm_Name][U_Name] FROM [dbo].[Program]
GO

 

.aspx页面的html,使用自定义模版<ItemTemplate>和<EditItemTemplate>,前者是显示非编辑状态,需要把CheckBoxList的 Enabled设为"false",即是说不能让用户可选择;而在编辑模版时,与<ItemTemplate>的CheckBoxList设为相反。其它相关的GridView的Edit,Update,Cancel和Delete可参考另外一篇:http://www.cnblogs.com/insus/articles/1944295.html

View Code
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="GridView1_RowDataBound"
            OnRowCancelingEdit
="GridView1_OnCancelCommand" OnRowEditing="GridView1_OnEditCommand"
            OnRowUpdating
="GridView1_OnUpdateCommand">
            
<Columns>
                
<asp:TemplateField HeaderText="Nbr">
                    
<ItemTemplate>
                        
<%Eval("Program_nbr"%>
                    
</ItemTemplate>
                
</asp:TemplateField>
                
<asp:TemplateField HeaderText="Pgm_Name">
                    
<ItemTemplate>
                        
<%Eval("Pgm_Name"%>
                    
</ItemTemplate>
                
</asp:TemplateField>
                
<asp:TemplateField HeaderText="MyCode">
                    
<ItemTemplate>
                        
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatColumns="4" RepeatDirection="Horizontal"
                            Enabled
="false">
                        
</asp:CheckBoxList>
                    
</ItemTemplate>
                    
<EditItemTemplate>
                        
<asp:CheckBoxList ID="CheckBoxList2" runat="server" RepeatColumns="4" RepeatDirection="Horizontal">
                        
</asp:CheckBoxList>
                    
</EditItemTemplate>
                
</asp:TemplateField>
                
<asp:TemplateField HeaderText="Edit">
                    
<HeaderStyle BorderWidth="1" BorderColor="#c0c0c0" Width="30" />
                    
<ItemStyle BorderWidth="1" BorderColor="#c0c0c0" />
                    
<ItemTemplate>
                        
<asp:Button ID="Button1" runat="server" Text="Edit" CommandName="Edit" />
                    
</ItemTemplate>
                    
<EditItemTemplate>
                        
<asp:Button ID="Button2" runat="server" Text="Update" CommandName="Update" />
                        
<asp:Button ID="Button3" runat="server" Text="Cancel" CommandName="Cancel" />
                    
</EditItemTemplate>
                
</asp:TemplateField>
            
</Columns>
        
</asp:GridView>


 .aspx.cs,只帖出重点部分:

View Code
 protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        DataRowView drv 
= (DataRowView)e.Row.DataItem;

        
if (e.Row.RowType == DataControlRowType.DataRow)
        {
            
if (e.Row.FindControl("CheckBoxList1"!= null)
            {
                EmbedCBL(e, 
"CheckBoxList1", drv["U_Name"].ToString());
            }

            
if (e.Row.FindControl("CheckBoxList2"!= null)
            {               
                EmbedCBL(e, 
"CheckBoxList2", drv["U_Name"].ToString());
            }
        }
    }

    
private void EmbedCBL(GridViewRowEventArgs e,string cblId, string Datakey)
    {
        CheckBoxList cbl 
= (CheckBoxList)e.Row.FindControl(cblId);
        
string myCode = objDevCodes.GetMyCodeByUser(Datakey);
        
string[] cde = myCode.Split(',');
        objCbl.CheckBoxListParse(cbl, objDevCodes.GetDevCodes(), 
"CodeName""DC_nbr", cde);
    }

    
protected void GridView1_OnUpdateCommand(object sender, GridViewUpdateEventArgs e)
    {
        CheckBoxList cbl 
= (CheckBoxList)GridView1.Rows[e.RowIndex].FindControl("CheckBoxList2");

        
string nbr = GetCheckBoxListSelectedValue(cbl);
        objDevCodes.InsertOrUpdate(
"Insus.NET", nbr);  //注意一下,此"Insus.NET"键,因为此是Demo,所以写死了。真正不能这样子喔。

        GridView1.EditIndex 
= -1;
        Data_Binding();
    }

 

 结果可浏览(下图是一个gif动画,如果没有看到动画效果,尝试刷新一次网页):

 

Demo5,这部分演示,Insus.NET需要改变一下它的存储方式,不想以"3,8,5,2,9"相似阵列方式存储,改用整型存储。首先把表[MyProfile]的字段MyCode的数据类型由NVARCHAR改为BIGINT. 

 

 

修改存储过程[dbo].[usp_MyProfile_IntOrUpd]:

View Code
ALTER PROCEDURE [dbo].[usp_MyProfile_IntOrUpd]
(
    
@U_Name NVARCHAR(30),
    
@MyCode BIGINT   --数据类型由NVARCHAR(100)改为BIGINT
)
AS

SELECT [U_Name],[MyCode] FROM [dbo].[MyProfile] WHERE [U_Name] = @U_Name

IF @@ROWCOUNT <= 0 
    
INSERT INTO [dbo].[MyProfile] ([U_Name],[MyCode]VALUES (@U_Name,@MyCode)
ELSE 
    
UPDATE [dbo].[MyProfile] SET [MyCode] = @MyCode  WHERE [U_Name] = @U_Name

 

修改DevCodes类别的InsertOrUpdate(xxx)方法。

View Code
  public void InsertOrUpdate(string uname, long mycode)
        {
            Parameter[] parameter 
= { 
                                      
new Parameter("@U_Name",SqlDbType.NVarChar,30,uname),
                                      
new Parameter("@MyCode",SqlDbType.BigInt,8,mycode)  
                                    };
            objBusinessBase.ExecuteProcedure(
"usp_MyProfile_IntOrUpd", parameter);
        }

 

去修改Button1_Click的事件,你会看到注释“由于每个选择的选项的主键是唯一,我们可以把选中的主键进行Math.Pow处理并相加,最后把相加的总值存起来”。

View Code
 protected void Button1_Click(object sender, EventArgs e)
    {
        
//string nbr = GetCheckBoxListSelectedValue(this.CheckBoxList1);
        ////objCbl.CheckBoxListParse(this.CheckBoxList2, objDevCodes.GetDevCodesByNbr(nbr), "CodeName", "DC_nbr");

        
long iV = 0;
        
foreach (ListItem li in CheckBoxList1.Items)
        {
            
if (li.Selected)
            {
               
//注意一下,下面使用Math.Pow处理。
                iV = iV + (long)Math.Pow(2, Convert.ToInt32(li.Value)); 
            }
        }

        
try
        {
            
//注意一下这个"Insus.NET",由于没有用户注册环境,如果有的话,应该取得当前用户ID   
            
//objDevCodes.InsertOrUpdate("Insus.NET", nbr);

            objDevCodes.InsertOrUpdate(
"Insus.NET", iV);
        }
        
catch (Exception ex)
        {
            InsusJsUtility objJs 
= new InsusJsUtility();
            objJs.JsAlert(ex.Message);
        }
    }

 

这时我们查看数据库,可以看到存储这样的结果: 

 

 为了看更详细一些,可以下图参考(2^2+2^12+2^14=20484):

  

 

由于数据类型改变,如果想把用户选择的选项显示在CheckBoxList为选中的状态,还需要改一下DevCodes类别的GetMyCodeByUser(xxx)方法。

View Code
  //获取用户保存的选择的数据
        public long GetMyCodeByUser(string uname)
        { 
              Parameter[] parameter 
= {
                                      
new Parameter("@U_Name",SqlDbType.NVarChar,30,uname)
                                  };
              
return Convert.ToInt64(objBusinessBase.ExecuteProcedureScalar("usp_MyProfile_GetByUser", parameter));
        }

 

接下来是显示绑定的代码:

View Code
private void Data_Binding()
    {
        
//从数据库取出用户选择的选项
        long  myCode = objDevCodes.GetMyCodeByUser("Insus.NET");

        
this.CheckBoxList1.DataSource = objDevCodes.GetDevCodes();
        
this.CheckBoxList1.DataTextField = "CodeName";
        
this.CheckBoxList1.DataValueField = "DC_nbr";
        
this.CheckBoxList1.DataBind();

       
//foreach CheckBoxList控件
        foreach (ListItem li in CheckBoxList1.Items)
        {
           
//Math.Pow处理存储结果
            long k = (long)Math.Pow (2,Convert.ToInt32(li.Value));

            
//如果匹配为true,反之为false
            li.Selected = ((myCode & k) == k) ? true : false;
        }
    }

 

 运行结果:

 

此Demo5方法,有点限制不足,就是选项不能超过32个选项,在Insus.NET开发过专案中基本没有超过32个的,所以也是Insus.NET最喜欢使用的方法。

 

posted @ 2011-06-17 16:42  Insus.NET  阅读(6257)  评论(5编辑  收藏  举报