Solved

Checkbox custom control doesn't fire event when unchecked

Posted on 2008-06-18
2
1,466 Views
Last Modified: 2008-06-27
HI experts,

I've built a checkbox custom control, the problem is when I check the checkbox the checkchanged event is fired but if I uncheck it, it doesn't fire.
Attach to this is the complete code of my control.

Thanks


Imports System

Imports System.Collections

Imports System.ComponentModel

Imports System.Web.UI

Imports System.Web.UI.WebControls
 
 

<Designer(GetType(ChkDesigner))> _

Public Class HQCheckBox
 

#Region "Init"
 

    Inherits System.Web.UI.WebControls.WebControl
 
 

    Implements INamingContainer

    Implements IPostBackDataHandler
 
 
 

    Protected ChkLabel As Label = New Label

    Public ctlChk As CheckBox = New CheckBox

    Private hfReadonly As HiddenField

    Private hfChecked As HiddenField

    Private hfTBField As HiddenField

    Private hfLabel As HiddenField

    Private hfCtlID As HiddenField

    Private hfGroup As HiddenField
 
 

    Public Event CheckChanged As EventHandler
 
 

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
 

        Dim strScript As String

        Dim strID As String = Replace(Me.UniqueID, ":", "_")

        strScript = My.Resources.HQCheckBoxEvent

        strScript = Replace(strScript, "HQChkCtlID", strID)

        strScript = Replace(strScript, "HQOrigID", Me.ID)
 

        Page.ClientScript.RegisterStartupScript(GetType(String), strID & "ChkEventScript", strScript)
 

        'Au postback les propriétés du controles prennes leurs valeurs des champs cachés

        If Page.IsPostBack Then

            EnsureChildControls()

            'Propriété readonly

            Me.ReadOnly = CType(hfReadonly.Value, Boolean)

            'Propriété Checked

            Me.Checked = CType(hfChecked.Value, Boolean)
 

            Me.TBFieldName = CType(hfTBField.Value, String)
 

            Me.Label = CType(hfLabel.Value, String)
 

            Me.ID = CType(hfCtlID.Value, String)
 

            Me.Group = CType(hfGroup.Value, String)
 
 
 

        End If

        MyBase.OnLoad(e)

    End Sub

    Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)

        'Avant le render du controle on stocke la valeur des propriété dans les champs cachés
 

        'Propriété readonly

        hfReadonly.Value = CType(Me.ReadOnly, Boolean)

        'Propriété checked

        hfChecked.Value = CType(Me.Checked, Boolean)
 

        hfTBField.Value = CType(Me.TBFieldName, String)
 

        hfLabel.Value = CType(Me.Label, String)
 

        hfCtlID.Value = CType(Me.ID, String)
 

        hfGroup.Value = CType(Me.Group, String)
 
 
 

        MyBase.OnPreRender(e)

    End Sub

   
 
 

    Protected Overridable Sub OnClick(ByVal e As EventArgs)

        RaiseEvent CheckChanged(Me, e)

    End Sub
 

    Private Sub ctlChk_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs)

        OnClick(e)

    End Sub
 

    Public Sub New()
 

        AddHandler ctlChk.CheckedChanged, AddressOf ctlChk_CheckedChanged
 

    End Sub
 

    Public Sub RaisePostDataChangedEvent() Implements System.Web.UI.IPostBackDataHandler.RaisePostDataChangedEvent
 
 

    End Sub
 
 

    Public Function LoadPostData(ByVal postDataKey As String, ByVal postCollection As System.Collections.Specialized.NameValueCollection) As Boolean Implements System.Web.UI.IPostBackDataHandler.LoadPostData
 

    End Function

    Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
 
 

        Dim strScript As String

        strScript = Page.ClientScript.GetWebResourceUrl(Me.GetType(), "HQ.HQCheckBox.js")

        Page.ClientScript.RegisterClientScriptInclude("HQ.HQCheckBox.js", strScript)
 

        MyBase.OnInit(e)

        EnsureChildControls()
 
 

        If Not Page Is Nothing Then

            Page.RegisterRequiresPostBack(Me)

        End If
 
 

        If Not Me.AutoPostBack Then

            ctlChk.AutoPostBack = False

            RemoveHandler ctlChk.CheckedChanged, AddressOf ctlChk_CheckedChanged

        Else

            ctlChk.AutoPostBack = True

        End If
 

    End Sub
 

#End Region
 

#Region "Hidden properties"

    <Browsable(False)> _

  Public Overrides Property EnableViewState() As Boolean

        Get

            Return MyBase.EnableViewState

        End Get

        Set(ByVal value As Boolean)

            MyBase.EnableViewState = value

        End Set

    End Property
 

    <Browsable(False)> _

      Public Overrides Property AccessKey() As String

        Get

            Return MyBase.AccessKey

        End Get

        Set(ByVal value As String)

            MyBase.AccessKey = value

        End Set

    End Property

    <Browsable(False)> _

   Public Overrides Property Visible() As Boolean

        Get

            Return MyBase.Visible

        End Get

        Set(ByVal value As Boolean)

            MyBase.Visible = value

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides Property BackColor() As System.Drawing.Color

        Get

            Return MyBase.BackColor

        End Get

        Set(ByVal value As System.Drawing.Color)

            MyBase.BackColor = value

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides Property BorderColor() As System.Drawing.Color

        Get

            Return MyBase.BorderColor

        End Get

        Set(ByVal value As System.Drawing.Color)

            MyBase.BorderColor = value

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides Property BorderStyle() As System.Web.UI.WebControls.BorderStyle

        Get

            Return MyBase.BorderStyle

        End Get

        Set(ByVal value As System.Web.UI.WebControls.BorderStyle)

            MyBase.BorderStyle = value

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides Property BorderWidth() As System.Web.UI.WebControls.Unit

        Get

            Return MyBase.BorderWidth

        End Get

        Set(ByVal value As System.Web.UI.WebControls.Unit)

            MyBase.BorderWidth = value

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides Property CssClass() As String

        Get

            Return MyBase.CssClass

        End Get

        Set(ByVal value As String)

            MyBase.CssClass = value

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides Property EnableTheming() As Boolean

        Get

            Return MyBase.EnableTheming

        End Get

        Set(ByVal value As Boolean)

            MyBase.EnableTheming = value

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides ReadOnly Property Font() As System.Web.UI.WebControls.FontInfo

        Get

            Return MyBase.Font

        End Get

    End Property

    <Browsable(False)> _

    Public Overrides Property ForeColor() As System.Drawing.Color

        Get

            Return MyBase.ForeColor

        End Get

        Set(ByVal value As System.Drawing.Color)

            MyBase.ForeColor = value

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides Property Height() As System.Web.UI.WebControls.Unit

        Get

            Return MyBase.Height

        End Get

        Set(ByVal value As System.Web.UI.WebControls.Unit)

            MyBase.Height = value

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides Property SkinID() As String

        Get

            Return MyBase.SkinID

        End Get

        Set(ByVal value As String)

            MyBase.SkinID = value

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides Property Width() As System.Web.UI.WebControls.Unit

        Get

            Return MyBase.Width

        End Get

        Set(ByVal value As System.Web.UI.WebControls.Unit)

            MyBase.Width = value

        End Set

    End Property
 

#End Region
 
 

#Region "Properties"
 

    Public Property [Label]() As String

        'Étiquette du controle

        Get

            Dim o As Object = ViewState("ChkLabel")

            If o Is Nothing Then

                Return "HQCheckBox"

            End If

            Return CType(ViewState("ChkLabel"), String)

        End Get

        Set(ByVal Value As String)

            ViewState("ChkLabel") = Value

            FormatCtl()

        End Set

    End Property
 

    Public Property [LabelLength]() As Integer

        'Longueur de l'étiquette

        Get

            Dim o As Object = ViewState("ChkLabelLength")

            If o Is Nothing Then

                Return 100

            End If

            Return CType(ViewState("ChkLabelLength"), Integer)

        End Get

        Set(ByVal Value As Integer)

            ViewState("ChkLabelLength") = Value

            FormatCtl()

        End Set

    End Property

    Public Property [ReadOnly]() As Boolean

        'Détermine si on peut éditer les données

        Get

            Dim o As Object = ViewState("ChkReadOnly")

            If o Is Nothing Then

                Return False

            End If

            Return CType(ViewState("ChkReadOnly"), Boolean)

        End Get

        Set(ByVal Value As Boolean)

            ViewState("ChkReadOnly") = Value

            FormatCtl()

        End Set

    End Property

    Public Property [Hidden]() As Boolean

        'Détermine si on peut éditer les données

        Get

            Dim o As Object = ViewState("Hidden")

            If o Is Nothing Then

                Return False

            End If

            Return CType(ViewState("Hidden"), Boolean)

        End Get

        Set(ByVal Value As Boolean)

            ViewState("Hidden") = Value

            FormatCtl()

        End Set

    End Property

    Public Property [CheckOnLeft]() As Boolean

        'Détermine si la case est à droite ou a gauche de l'étiquette

        Get

            Dim o As Object = ViewState("CheckOnLeft")

            If o Is Nothing Then

                Return False

            End If

            Return CType(ViewState("CheckOnLeft"), Boolean)

        End Get

        Set(ByVal Value As Boolean)

            ViewState("CheckOnLeft") = Value

            FormatCtl()

        End Set

    End Property

    <Browsable(False)> _

    Public Property [isChecked]() As Boolean

        'Pour garder l'état du coté client

        Get

            Dim o As Object = ViewState("isChecked")

            If o Is Nothing Then

                Return False

            End If

            Return CType(ViewState("isChecked"), Boolean)

        End Get

        Set(ByVal Value As Boolean)

            ViewState("isChecked") = Value

            FormatCtl()

        End Set

    End Property

    Public Property [AutoPostBack]() As Boolean

        'Détermine si un postback est généré lors d'un changement

        Get

            Dim o As Object = ViewState("ChkAutoPostBack")

            If o Is Nothing Then

                Return True

            End If

            Return CType(ViewState("ChkAutoPostBack"), Boolean)

        End Get

        Set(ByVal Value As Boolean)

            ViewState("ChkAutoPostBack") = Value

            FormatCtl()

        End Set

    End Property

    Public Property [Checked]() As Boolean

        'État du checkbox

        Get
 

            Return ctlChk.Checked
 

        End Get

        Set(ByVal Value As Boolean)
 

            ctlChk.Checked = Value

            FormatCtl()

        End Set

    End Property

    Public Property TabIndx() As Integer

        'Le TabIndex du controle, on utilise celui ci au lieu

        'du Tabindex du controle global pour ne pas que le curseur

        'se positionne sur l'étiquette

        Get

            Dim o As Object = ViewState("CtrlTabIndex")

            If o Is Nothing Then

                Return -1

            End If

            Return CType(ViewState("CtrlTabIndex"), Integer)

        End Get

        Set(ByVal Value As Integer)

            ViewState("CtrlTabIndex") = Value

            FormatCtl()

        End Set

    End Property

    <Browsable(False)> _

    Public Overrides Property TabIndex() As Short

        Get

            Return MyBase.TabIndex

        End Get

        Set(ByVal value As Short)

            MyBase.TabIndex = value

        End Set

    End Property
 

    Public Property [Security]() As String

        'utilisé pour la gestion de sécurité par champ

        Get

            Return CType(ViewState("ChkSecurity"), String)

        End Get

        Set(ByVal Value As String)

            ViewState("ChkSecurity") = Value

            FormatCtl()

        End Set

    End Property

    Public Property [Group]() As String

        'utilisé pour gérer des groupes de champs dans les écrans

        Get

            Return CType(ViewState("Group"), String)

        End Get

        Set(ByVal Value As String)

            ViewState("Group") = Value

        End Set

    End Property

    Public Property [TBFieldName]() As String

        'utilisé pour spécifié le nom exact du champ dans la table SQL

        Get

            Return CType(ViewState("TBFieldName"), String)

        End Get

        Set(ByVal Value As String)

            ViewState("TBFieldName") = Value

            FormatCtl()

        End Set

    End Property

#End Region
 

#Region "Constructors"

    Protected Overloads Overrides Sub CreateChildControls()
 

        FormatCtl()
 

        Dim tb As New Table

        tb.CellPadding = 0

        tb.CellSpacing = 0

        Dim rr As New TableRow

        Dim c1 As New TableCell

        Dim c2 As New TableCell
 

        'Propriété readonly

        hfReadonly = New HiddenField

        hfReadonly.ID = "_ronly"

        Controls.Add(hfReadonly)

        'Propriété checked

        hfChecked = New HiddenField

        hfChecked.ID = "_checked"

        Controls.Add(hfChecked)
 

        'Propriété TBFieldName

        hfTBField = New HiddenField

        hfTBField.ID = "_tbfield"

        Controls.Add(hfTBField)
 

        hfLabel = New HiddenField

        hfLabel.ID = "_label"

        Controls.Add(hfLabel)

        hfCtlID = New HiddenField

        hfCtlID.ID = "_ctlid"

        Controls.Add(hfCtlID)

        hfGroup = New HiddenField

        hfGroup.ID = "_group"

        Controls.Add(hfGroup)
 
 
 

        ChkLabel.ID = "_lbl"

        ctlChk.ID = "_chk"

        ctlChk.Attributes.Add("onClick", "setVal('" & Me.ID & "','" & Me.ID & "')")
 
 
 
 

        c1.Style.Add("BORDER-BOTTOM", "white 1px solid")

        c2.Style.Add("BORDER-BOTTOM", "white 1px solid")

        c1.TabIndex = -1

        c2.TabIndex = -1
 

        If Me.CheckOnLeft Then

            c1.Controls.Add(ctlChk)

            c2.Controls.Add(ChkLabel)
 

        Else

            c1.Controls.Add(ChkLabel)

            c2.Controls.Add(ctlChk)
 

        End If
 
 
 

        rr.Cells.Add(c1)

        rr.Cells.Add(c2)

        tb.Rows.Add(rr)
 

        Controls.Add(tb)
 

        tb.Visible = Not Me.Hidden
 
 

    End Sub
 
 
 
 
 

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
 

        Dim pos As String = CType(Me.Style("TOP").Split("px")(0) + 1, String)
 

        writer.AddStyleAttribute("LEFT", Me.Style("LEFT"))

        writer.AddStyleAttribute("TOP", pos & "px")

        writer.AddStyleAttribute("POSITION", Me.Style("POSITION"))

        writer.AddStyleAttribute("Z-INDEX", Me.Style("Z-INDEX"))
 
 

        If Not Me.Site Is Nothing AndAlso Me.Site.DesignMode = True Then

            ' Design Mode
 

        Else

            ' Run-time

            Me.Style.Clear()

        End If
 
 

        FormatCtl()
 

        writer.Write("<HQCTL class=""HQCheckBox"" id='hqCtl_" & Me.ID & "' name='group(" & Me.Group & ")'>")

        writer.RenderBeginTag("div class=""HQCheckBox"" id='jsObj_" & Me.ID & "' name='group(" & Me.Group & ")'")
 

        writer.Write(("<script language=""javascript"">var arr" & Me.ID & " = new Array();</script>") & vbCr)

        writer.Write(("<script language=""javascript"">initChkBox('" & Me.ID & "');</script>") & vbCr)
 
 
 
 

        MyBase.Render(writer)
 
 

        writer.RenderEndTag()
 

        writer.Write("</HQCTL>")

    End Sub
 

#End Region
 

#Region "Format"

    Sub FormatCtl()
 

        'Etiquette du controle

        With ChkLabel

            If Me.CheckOnLeft Then

                .Style.Add("PADDING-RIGHT", "5px")

                .Style.Add("TEXT-ALIGN", "right")

            Else

                .Style.Add("PADDING-LEFT", "5px")

                .Style.Add("TEXT-ALIGN", "left")

            End If

            .Height = Unit.Pixel(21)

            '.Style.Add("BORDER-BOTTOM", "white 1px solid")
 

            .Style.Add("FONT-FAMILY", "Tahoma")

            .Style.Add("FONT-SIZE", "10pt")

            .BorderStyle = BorderStyle.None

            .Text = Me.Label

            'If Me.ReadOnly Then

            '    ctlChk.Enabled = False

            'Else

            '    ctlChk.Enabled = True

            'End If

            If Me.LabelLength >= 3 Then

                .Width = Unit.Pixel(Me.LabelLength - 7)

            Else

                .Width = Unit.Pixel(Me.LabelLength)

            End If

            .TabIndex = -1

        End With
 

        ctlChk.TabIndex = Me.TabIndx

        ctlChk.EnableViewState = False
 
 

        Me.TabIndex = -1
 

    End Sub

#End Region
 
 

    Private Sub HQCheckBox_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init

        Page.RegisterRequiresPostBack(Me)
 

    End Sub

End Class
 

Public Class ChkDesigner

    Inherits System.Web.UI.Design.ControlDesigner
 
 

    Public Overrides Function getdesignTimeHTML() As String

        Dim writer As New System.IO.StringWriter
 
 
 

        Dim html As New HtmlTextWriter(writer)
 
 

        Dim ctl As HQCheckBox = CType(Component, HQCheckBox)
 

        writer.Write(("<DIV style=""LEFT: " & ctl.Style("LEFT") & "; " & _

                     "TOP: " & ctl.Style("TOP") & "; " & _

                     "POSITION: absolute; " & _

                     "Z-INDEX: " & ctl.Style("Z-INDEX") & "; " & _

                     "WIDTH: " & ctl.LabelLength + 50 & "; " & _

                     "HEIGHT: " & ctl.Height.ToString & """>") & vbCr)
 

        ctl.Style.Remove("POSITION")
 

        ctl.RenderControl(html)
 

        writer.Write("</DIV>")
 
 
 

        Return writer.ToString
 

    End Function
 
 

End Class

Open in new window

0
Comment
Question by:hqdev
2 Comments
 
LVL 12

Expert Comment

by:renjurdevan
ID: 21819230
OnInit you have code like
 If Not Me.AutoPostBack Then
            ctlChk.AutoPostBack = False
            RemoveHandler ctlChk.CheckedChanged, AddressOf ctlChk_CheckedChanged
        Else
            ctlChk.AutoPostBack = True
        End If

Which will remove Handler if Autopost back is false. So it will not get fire once check box get unchecked.. Once it unchecked it agan add handler in Constructor so it get fires when checked..



0
 

Accepted Solution

by:
hqdev earned 0 total points
ID: 21821247
This autopostback property is for using the control on client side instead of server side.
And if I set this property to true both the check and uncheck event should trigger the CheckedChanged event.

Since yesterday, I added the line RegisterRequiresPostback , deleted my bin and obj directory, rebuild my controls and now it's working!!
The listing of this message included that line but it wasn't working, probably rebuilding the controls from scratch implemented that last change and solved the problem.

So the solution of that problem is adding the RegisterRequirerPostback line who's forcing a postback on both the check and uncheck.
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now