.<1> - }
Consuming the Control
ASPX Markup Code
To use this control, you need to follow the instructions in the Consuming Custom Controls in ASP.NET article.
Placing the control
<abc:CheckedListBox Columns="3" ID="uxRegionsListBox"
runat="server" EnableViewState="true"
/>
ASPX Markup Code for Validation Control
<asp:CustomValidator runat="server" Text="" Display="Dynamic"
SetFocusOnError="true" ValidationGroup="MainValidationGroup"
EnableClientScript="true"
ClientValidationFunction="validateRegions"
OnServerValidate="uxRegionsRequiredValidator_Validate"
ID="uxRegionsRequiredValidator"
ErrorMessage="At least one region must be selected."
>
<asp:Image ID="Image5" runat="server"
ImageUrl="~/images/Exclamation.PNG" />
</asp:CustomValidator>
JavaScript Code for Validation
Be sure to change "uxRegionsListBox" to the name of your checkbox control.
// This is a helper function
function validateCheckedListBox(e, id)
{
var selectedCheckBoxes;
selectedCheckBoxes = 0;
for (i = 0; i < document.forms[0].elements.length; i++)
{
var ctl;
ctl = document.forms[0].elements[i];
if (ctl.type == "checkbox" & ctl.id.indexOf(id) >= 0)
{
if (ctl.checked)
selectedCheckBoxes++;
}
}
e.IsValid = (selectedCheckBoxes > 0);
}
// This is the function called on the client side to validate the checked-list-box.
function validateRegions(sender, e)
{
validateCheckedListBox(e, "uxRegionsListBox");
}
Code-Behind
VB.NET (in a GridView)
'--------------------------------------------------------------------------------------------------
Private Sub uxSearchResultsGridView_RowDataBound(ByVal sender As Object, ByVal e As _
GridViewRowEventArgs) Handles uxSearchResultsGridView.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
UserControl_CheckedListBox.BindCheckedListBox(e.Row, "uxRegionsListBox", GetRegions(), _
"Name", "RegionId", "Regions")
End If
End Sub
'--------------------------------------------------------------------------------------------------
Protected Sub uxRegionsRequiredValidator_Validate(ByVal sender As Object, ByVal e As _
ServerValidateEventArgs)
e.IsValid = (uxRegionsListBox.ItemsChecked > 0)
End Sub
C#
//TODO: Add C# code here
Code for the Control
ASPX Markup for VB.NET
<%@ Control Language="VB" AutoEventWireup="false" CodeFile="CheckedListBox.ascx.vb"
Inherits="UserControls_CheckedListBox" EnableViewState="true" %>
<div style="overflow:auto;" runat="server" id="uxMainDiv" />
ASPX Markup for C#
<%@ Control Language="C#" AutoEventWireup="false" CodeFile="CheckedListBox.ascx.cs"
Inherits="UserControls_CheckedListBox" EnableViewState="true" %>
<div style="overflow:auto;" runat="server" id="uxMainDiv" />
VB.NET
Imports System.Data
Imports System.Collections.Generic
<ValidationProperty("ItemsChecked")> _
Partial Class UserControls_CheckedListBox
Inherits System.Web.UI.UserControl
Private _dataSource As DataTable
Private _dataTextField As String
Private _dataValueField As String
Private _items As Dictionary(Of String, CheckBox)
Private _itemValues As Dictionary(Of String, Integer)
Private _columns As Integer
'----------------------------------------------------------------------------------------------
Public Sub New()
_items = New Dictionary(Of String, CheckBox)
_itemValues = New Dictionary(Of String, Integer)
_columns = 1
End Sub
'----------------------------------------------------------------------------------------------
Public Property Columns() As Integer
Get
Return _columns
End Get
Set(ByVal value As Integer)
_columns = value
End Set
End Property
'----------------------------------------------------------------------------------------------
Public Property DataSource() As DataTable
Get
Return _dataSource
End Get
Set(ByVal value As DataTable)
_dataSource = value
End Set
End Property
'----------------------------------------------------------------------------------------------
Public Property DataTextField() As String
Get
Return _dataTextField
End Get
Set(ByVal value As String)
_dataTextField = value
End Set
End Property
'----------------------------------------------------------------------------------------------
Public Property DataValueField() As String
Get
Return _dataValueField
End Get
Set(ByVal value As String)
_dataValueField = value
End Set
End Property
'----------------------------------------------------------------------------------------------
Public Overrides Sub DataBind()
Dim i As Integer = 0
Dim tbl As Table = New Table()
tbl.CellPadding = 3
tbl.CellSpacing = 0
tbl.BorderStyle = BorderStyle.None
Dim tr As TableRow = Nothing
If _dataSource IsNot Nothing Then
For Each row As DataRow In _dataSource.Rows
Dim text As String = row(_dataTextField)
Dim value As Integer = Convert.ToInt32(row(_dataValueField))
Dim cb As CheckBox = New CheckBox
cb.Text = text
cb.Checked = False
cb.CssClass = "stdData"
_items.Add(text, cb)
_itemValues.Add(text, value)
Dim td As TableCell = New TableCell()
td.Controls.Add(cb)
If i Mod _columns = 0 Then
tr = New TableRow()
tbl.Rows.Add(tr)
End If
tr.Cells.Add(td)
i += 1
Next
End If
uxMainDiv.Controls.Add(tbl)
End Sub
'----------------------------------------------------------------------------------------------
Public ReadOnly Property Items() As Dictionary(Of String, CheckBox)
Get
Return _items
End Get
End Property
'----------------------------------------------------------------------------------------------
Public ReadOnly Property ItemValues() As Dictionary(Of String, Integer)
Get
Return _itemValues
End Get
End Property
'----------------------------------------------------------------------------------------------
''' <summary>
''' This property is used only for validation purposes.
''' </summary>
Public ReadOnly Property ItemsChecked() As Integer
Get
Dim result As Integer = 0
For Each key As String In _itemValues.Keys
If _items(key).Checked Then
result += 1
Exit For
End If
Next
Return result
End Get
End Property
'----------------------------------------------------------------------------------------------
''' <summary>
''' This method should be called UNCONDITIONALLY in the Page_Load event. See also the Bind()
''' method.
''' </summary>
Public Sub InitCheckBoxes(ByVal itemSource As DataTable, ByVal dataTextField As String, ByVal _
dataValueField As String)
Me.DataSource = itemSource
Me.DataTextField = dataTextField
Me.DataValueField = dataValueField
Me.DataBind()
End Sub
'----------------------------------------------------------------------------------------------
''' <summary>
''' This method should be called only if: Not Page.IsPostBack! See also the Init() method
''' </summary>
Public Sub Bind(ByVal checkedValues As String, ByVal delimiter As String)
Dim items() As String = checkedValues.ToString().Split(delimiter)
For Each item As String In items
Me.Items(item).Checked = True
Next
End Sub
'----------------------------------------------------------------------------------------------
''' <summary>
''' Use this method to create a checked listbox within a GridView control when the row
''' goes into edit mode. MUST BE CALLED FROM THE ROWDATABOUND EVENT HANDLER.
''' </summary>
Public Shared Sub BindCheckedListBox(ByVal gvRow As GridViewRow, ByVal checkedListBox As String, _
ByVal itemSource As DataTable, ByVal dataTextField As String, ByVal dataValueField As String, _
ByVal fieldName As String)
Dim clb As UserControl_CheckedListBox = gvRow.FindControl(checkedListBox)
If clb IsNot Nothing Then
clb.DataSource = itemSource
clb.DataTextField = dataTextField
clb.DataValueField = dataValueField
clb.DataBind()
Dim row As DataRow = Nothing
Dim drv As DataRowView = CType(gvRow.DataItem, DataRowView)
If drv IsNot Nothing Then
row = drv.Row
End If
If row IsNot Nothing Then
Dim regions() As String = row(fieldName).ToString().Split("^"c)
For Each region As String In regions
clb.Items(region).Checked = True
Next
End If
End If
End Sub
End Class
C#
//TODO: Add the C# code