.net - 如何在 CheckedListbox 中 CheckOnClick 但仅在复选框上方时?

标签 .net checkedlistbox

我有一个 CheckedListBox。我希望能够在单击文本时选择项目,但在单击左侧的复选框区域时选中/取消选中它们。如果我设置 CheckOnClick,那么每当我单击时,即使在文本上,项目也会被选中和取消选中,所以这不好。但是,如果我清除 CheckOnClick,则必须单击两次才能选中和取消选中。

我的第一个想法是处理 MouseClick 或 MouseDown 事件并调用 IndexFromPoint 以找出单击了哪一行。然后我猜复选框在左边,从 x=position 从 0 到,比方说,ItemRectangle.Height。根据与左侧的距离,我可以选择或选中/取消选中。

问题是是否有更好的方法来确定鼠标是在复选框上还是在文本上。不同的样式可以有不同大小的复选框,并且可以将它们放在左侧、右侧等...

最佳答案

感谢 SLaks,我写了这个并且它似乎有效。要使用它,CheckOnClick 必须为真,CheckInCheckbox 也必须为真。继承自 CheckedListbox。

想法是找出复选框的位置,如果单击在复选框之外,则将检查状态设置为相反的位置。稍后,当基类 CheckedListbox 接收到鼠标点击时,它会再次将复选框状态更改回原来的状态。

来回更改状态有点 hacky,但我找不到任何其他方法来绕过 CheckedListbox 使用 SelectedIndex 来选中/取消选中的方式,这也是一种 hack。

Private MyCheckInCheckbox As Boolean = False

''' <summary>
''' Only change the checkbox value when clicking on the box
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property CheckInCheckbox() As Boolean
    Get
        Return MyCheckInCheckbox
    End Get
    Set(ByVal value As Boolean)
        MyCheckInCheckbox = value
    End Set
End Property

Private Sub MyCheckedListBox_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
    If CheckInCheckbox Then
        Dim border As Integer = 1
        Dim index As Integer = IndexFromPoint(e.Location)
        If index <> ListBox.NoMatches Then
            Dim bounds As Rectangle = Me.GetItemRectangle(index)
            Dim idealCheckSize As Integer
            If Application.RenderWithVisualStyles Then
                Dim cbState As VisualStyles.CheckBoxState
                Select Case Me.GetItemCheckState(index)
                    Case CheckState.Checked
                        cbState = VisualStyles.CheckBoxState.CheckedNormal
                    Case CheckState.Indeterminate
                        cbState = VisualStyles.CheckBoxState.MixedNormal
                    Case CheckState.Unchecked
                        cbState = VisualStyles.CheckBoxState.UncheckedNormal
                End Select
                Dim g As Graphics = Me.CreateGraphics
                idealCheckSize = CheckBoxRenderer.GetGlyphSize(g, cbState).Width
                g.Dispose()
            End If
            Dim centeringFactor As Integer = Math.Max((bounds.Height - idealCheckSize) \ 2, 0)
            If centeringFactor + idealCheckSize > bounds.Height Then
                centeringFactor = bounds.Height - idealCheckSize
            End If
            Dim box As Rectangle = New Rectangle(bounds.X + border, bounds.Y + centeringFactor, idealCheckSize, idealCheckSize)
            If RightToLeft = Windows.Forms.RightToLeft.Yes Then
                box.X = bounds.X + bounds.Width - idealCheckSize - border
            End If
            If Not box.Contains(e.Location) Then
                Me.SelectedIndex = index
                SetItemChecked(index, Not GetItemChecked(index))
            End If
        End If
    End If
End Sub

关于.net - 如何在 CheckedListbox 中 CheckOnClick 但仅在复选框上方时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1877800/

相关文章:

c# - 从列表或数据集中在选中的列表框中设置选中的项目

c# - 寻找具有图标支持的 CheckedListBox 控件

c# - 如何使用 FTP 获取基于模式匹配的文件列表?

c# - 从一开始就构建 IDocument 最有效的方法是什么

c# - 如何对 CheckedListBox 进行排序

c# - 如何循环遍历checkedlistbox并删除c#中的选定项目

c# - CheckedListBox 项目的工具提示?

c# - 执行存储为资源的 SQL 脚本

.net - RSA:在.NET 中使用公钥进行解密?

c# - 应该如何在 XML 属性值中处理 '\t' 字符?