zoukankan      html  css  js  c++  java
  • 构建一个更好的CheckedListBox控件

    问题 控件在使用选项卡控件时忘记项目的已检查状态。 用户可以选中或取消选中项目。 不能根据项的索引引用项。 解决方案 所有这些问题都可以通过使用自定义控件来解决。 自定义控件 下面的代码将AutoCheck属性(与复选框控件具有的属性相同)添加到CheckedListBox控件。它还实现了一个bug修复,并且允许引用控件中的项,就像您可以在组合框中引用它们一样。为了创建我们的BetterCheckedListBox控件,创建一个新的VB。NET类库项目,并将下面的代码复制到Class .vb中。隐藏,收缩,复制Code

    'Show the CheckedListBox icon in the Toolbox for our component
    <ToolboxBitmap(GetType(CheckedListBox))> _
    Public Class BetterCheckedListBox
    Inherits System.Windows.Forms.CheckedListBox
    '----------------------------------------------------------
    ' Class level variables 
    '----------------------------------------------------------
     Dim AllowChecks As Boolean 'Controls whether checkstate can be changed
     Dim ChkMember As String 'The DataColumn to use for checkstate
     Dim dt As DataTable 'Data to display
    '----------------------------------------------------------
    ' Bug Fix
    '----------------------------------------------------------
    ' When the CheckedListBox control is in a Tabcontrol 
    ' and that the Datasource property is used to fill
    ' up the item list, setting the clb's visible property
    ' to false, then to true, or flipping the tabs would
    ' cause the clb to "forget" the checks.
    '
    ' Implement Carl Mercier's workaround
    ' http://www.codeproject.com/cs/combobox/FixedCheckedListBox.asp
    '----------------------------------------------------------
     Public Overloads Property DataSource() As Object
      Get
       'Return our datatable variable
       DataSource = CType(dt, Object)
      End Get
      Set(ByVal value As Object)
       'Set our datatable variable
       dt = CType(value, DataTable)
       LoadData()
      End Set
     End Property
     Private Function LoadData()
      Dim bufAllowChecks = AllowChecks
      If AllowChecks = False Then
       'This is needed so we can change checkstates
        AllowChecks = True
      End If
      'Clear items
      MyBase.Items.Clear()
      'Fill it again
      Dim i As Integer
      For i = 0 To dt.DefaultView.Count - 1
       'Determine whether to check each item or not
       If dt.Rows(i).Item(ChkMember) = "1" Or _
         dt.Rows(i).Item(ChkMember) = "True" Then
        MyBase.Items.Add(dt.DefaultView.Item(i), True)
       Else
        MyBase.Items.Add(dt.DefaultView.Item(i), False)
       End If
      Next
      AllowChecks = bufAllowChecks
     End Function
     'Added or deleted records won't show without a refresh
     Public Overrides Sub Refresh()
      LoadData()
     End Sub
    '----------------------------------------------------------
    ' Allow / Lock Checkstate Functionality
    '----------------------------------------------------------
    ' Only let users check or uncheck items when you let them. 
    ' Note that you can't programmatically check or uncheck
    ' items either unless AllowChecks is True.
    '
    ' This is an emulation of the Checkbox control's AutoCheck
    ' property.
    '----------------------------------------------------------
    'Show our property under the Behavior section of the Properties window
    'So that it can be set at design time
    <System.ComponentModel.Description("Allow checkstate to be changed"), _
    System.ComponentModel.Category("Behavior")> _
     Public Property AutoCheck() As Boolean
      Get
       'Return our checkstate variable
       AutoCheck = AllowChecks
      End Get
      Set(ByVal value As Boolean)
       'Set our checkstate variable
       AllowChecks = value
      End Set
     End Property
     'Override the ItemCheck event with our own
     Protected Overrides Sub OnItemCheck(ByVal ice As _
               System.Windows.Forms.ItemCheckEventArgs)
      'Allow checks to be changed only if AutoCheck = True
      If AllowChecks = False Then
       ice.NewValue = ice.CurrentValue
      End If
     End Sub
    '----------------------------------------------------------
    ' Reference Item By It's Index Functionality
    '----------------------------------------------------------
    ' Wouldn't it be nice if you could reference items in a
    ' CheckedListBox control just like you can with a 
    ' ComboBox? Well now you can!
    '
    ' Obtain Checkstatus, Text, and Values via an items index
    '----------------------------------------------------------
    <System.ComponentModel.Description("Gets or sets the CheckMember")> _
     Public Property CheckMember() As String
      Get
       CheckMember = ChkMember
      End Get
      Set(ByVal value As String)
       ChkMember = value
      End Set
     End Property
    <System.ComponentModel.Description("Gets or sets an items's checkstate")> _
     Public Property Checked(ByVal index As Integer) As Boolean
      Get
       'Search for the item in CheckedIndices to see if its checked or not
       If MyBase.CheckedIndices.IndexOf(index) <> -1 Then
        Checked = True
       Else
        Checked = False
       End If
      End Get
      Set(ByVal value As Boolean)
       'Set item's checkstate
       Dim bufAllowChecks = AllowChecks
       If AllowChecks = False Then
        AllowChecks = True
       End If
       MyBase.SetItemChecked(index, value)
       AllowChecks = bufAllowChecks
      End Set
     End Property
    <System.ComponentModel.Description("Gets or sets an items's DisplayMember")> _
     Public Overloads Property Text(ByVal index As Integer) As String
      Get
       Text = dt.Rows(index).Item(MyBase.DisplayMember)
      End Get
      Set(ByVal value As String)
       dt.Rows(index).Item(MyBase.DisplayMember) = value
      End Set
     End Property
    <System.ComponentModel.Description("Gets or sets an items's ValueMember")> _
     Public Property Value(ByVal index As Integer) As String
      Get
       Value = dt.Rows(index).Item(MyBase.ValueMember)
      End Get
      Set(ByVal value As String)
       dt.Rows(index).Item(MyBase.ValueMember) = value
      End Set
     End Property
    End Class

    一旦这个项目被编译,复制输出,BetterCheckedListBox。dll, C:\Program Files\Microsoft Visual Studio . net 2003 IDE \ Common7 \ \ PublicAssemblies \。 然后右键单击工具箱,选择“添加/删除”,选择BetterCheckedListBox,然后单击OK将我们的自定义控件添加到工具箱。 演示项目 要创建我们的演示项目,请启动一个新的VB。并将下面的代码复制到Form1.vb中。运行该项目,下面还显示了演示的屏幕截图。隐藏,收缩,复制Code

    Public Class Form1
    Inherits System.Windows.Forms.Form
    #Region " Windows Form Designer generated code "
     Public Sub New()
      MyBase.New()
      InitializeComponent()
     End Sub
     Protected Overloads Overrides Sub _
       Dispose(ByVal disposing As Boolean)
      If disposing Then
       If Not (components Is Nothing) Then
        components.Dispose()
       End If
      End If
      MyBase.Dispose(disposing)
     End Sub
     Private components As System.ComponentModel.IContainer
     Friend WithEvents Button1 As System.Windows.Forms.Button
     Friend WithEvents BetterCheckedListBox1 As _
            BetterCheckedListBox.BetterCheckedListBox
     Friend WithEvents CheckBox1 As System.Windows.Forms.CheckBox
     Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
     Friend WithEvents Label1 As System.Windows.Forms.Label
     Friend WithEvents Label2 As System.Windows.Forms.Label
     Friend WithEvents Label3 As System.Windows.Forms.Label
     Friend WithEvents TextBox2 As System.Windows.Forms.TextBox
     Friend WithEvents Label4 As System.Windows.Forms.Label
     Friend WithEvents TextBox3 As System.Windows.Forms.TextBox
    <System.Diagnostics.DebuggerStepThrough()>_
     Private Sub InitializeComponent()
      Me.Button1 = New System.Windows.Forms.Button
      Me.BetterCheckedListBox1 = New _
        BetterCheckedListBox.BetterCheckedListBox
      Me.CheckBox1 = New System.Windows.Forms.CheckBox
      Me.TextBox1 = New System.Windows.Forms.TextBox
      Me.Label1 = New System.Windows.Forms.Label
      Me.Label2 = New System.Windows.Forms.Label
      Me.Label3 = New System.Windows.Forms.Label
      Me.TextBox2 = New System.Windows.Forms.TextBox
      Me.Label4 = New System.Windows.Forms.Label
      Me.TextBox3 = New System.Windows.Forms.TextBox
      Me.SuspendLayout()
      Me.Button1.Location = New System.Drawing.Point(24, 144)
      Me.Button1.Name = "Button1"
      Me.Button1.Size = New System.Drawing.Size(120, 23)
      Me.Button1.TabIndex = 2
      Me.Button1.Text = "Add New Person"
      Me.BetterCheckedListBox1.AutoCheck = True
      Me.BetterCheckedListBox1.CheckMember = Nothing
      Me.BetterCheckedListBox1.Location = New System.Drawing.Point(24, 24)
      Me.BetterCheckedListBox1.Name = "BetterCheckedListBox1"
      Me.BetterCheckedListBox1.Size = New System.Drawing.Size(120, 94)
      Me.BetterCheckedListBox1.TabIndex = 3
      Me.CheckBox1.Location = New System.Drawing.Point(24, 120)
      Me.CheckBox1.Name = "CheckBox1"
      Me.CheckBox1.Size = New System.Drawing.Size(120, 16)
      Me.CheckBox1.TabIndex = 5
      Me.CheckBox1.Text = "Lock CheckBoxes"
      Me.TextBox1.Location = New System.Drawing.Point(152, 24)
      Me.TextBox1.Name = "TextBox1"
      Me.TextBox1.TabIndex = 6
      Me.TextBox1.Text = ""
      Me.Label1.Location = New System.Drawing.Point(152, 8)
      Me.Label1.Name = "Label1"
      Me.Label1.Size = New System.Drawing.Size(100, 16)
      Me.Label1.TabIndex = 7
      Me.Label1.Text = "Checked:"
      Me.Label2.Location = New System.Drawing.Point(24, 8)
      Me.Label2.Name = "Label2"
      Me.Label2.Size = New System.Drawing.Size(100, 16)
      Me.Label2.TabIndex = 8
      Me.Label2.Text = "People:"
      Me.Label3.Location = New System.Drawing.Point(152, 56)
      Me.Label3.Name = "Label3"
      Me.Label3.Size = New System.Drawing.Size(100, 16)
      Me.Label3.TabIndex = 10
      Me.Label3.Text = "Text:"
      Me.TextBox2.Location = New System.Drawing.Point(152, 72)
      Me.TextBox2.Name = "TextBox2"
      Me.TextBox2.TabIndex = 9
      Me.TextBox2.Text = ""
      Me.Label4.Location = New System.Drawing.Point(152, 104)
      Me.Label4.Name = "Label4"
      Me.Label4.Size = New System.Drawing.Size(100, 16)
      Me.Label4.TabIndex = 12
      Me.Label4.Text = "Value:"
      Me.TextBox3.Location = New System.Drawing.Point(152, 120)
      Me.TextBox3.Name = "TextBox3"
      Me.TextBox3.TabIndex = 11
      Me.TextBox3.Text = ""
      Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
      Me.ClientSize = New System.Drawing.Size(272, 190)
      Me.Controls.Add(Me.Label4)
      Me.Controls.Add(Me.TextBox3)
      Me.Controls.Add(Me.Label3)
      Me.Controls.Add(Me.TextBox2)
      Me.Controls.Add(Me.Label2)
      Me.Controls.Add(Me.Label1)
      Me.Controls.Add(Me.TextBox1)
      Me.Controls.Add(Me.CheckBox1)
      Me.Controls.Add(Me.BetterCheckedListBox1)
      Me.Controls.Add(Me.Button1)
      Me.Name = "Form1"
      Me.Text = "BetterCheckedListBox Demo"
      Me.ResumeLayout(False)
     End Sub
    #End Region
     Dim dt As New DataTable
     Private Sub Button1_Click(ByVal sender As System.Object,_
              ByVal e As System.EventArgs) Handles Button1.Click
      Dim dr As DataRow = dt.NewRow
      dr(0) = "Person " & BetterCheckedListBox1.Items.Count + 1
      dr(1) = "x"
      dr(2) = 0 'Checked is False
      dt.Rows.Add(dr)
      'Force refresh in order to show changes
      BetterCheckedListBox1.Refresh()
     End Sub
     Private Sub Form1_Load(ByVal sender As System.Object,_
           ByVal e As System.EventArgs) Handles MyBase.Load
      'Load some items
      dt.Columns.Add("txt", GetType(String))
      dt.Columns.Add("val", GetType(String))
      dt.Columns.Add("chk", GetType(String))
      Dim i As Integer
      For i = 1 To 5
       Dim dr As DataRow = dt.NewRow
       dr(0) = "Person " & i
       dr(1) = i
       dr(2) = "True"
       dt.Rows.Add(dr)
      Next
      'Set DataBindings
      BetterCheckedListBox1.DisplayMember = "txt"
      BetterCheckedListBox1.ValueMember = "val"
      BetterCheckedListBox1.CheckMember = "chk"
      BetterCheckedListBox1.DataSource = dt
     End Sub
     Private Sub CheckBox1_CheckedChanged(ByVal sender As _
          System.Object, ByVal e As System.EventArgs) _
          Handles CheckBox1.CheckedChanged
      'Allow / Lock items
      BetterCheckedListBox1.AutoCheck = Not CheckBox1.Checked
     End Sub
     Private Sub BetterCheckedListBox1_SelectedIndexChanged(ByVal _
         sender As System.Object, ByVal e As _
         System.EventArgs) Handles _
         BetterCheckedListBox1.SelectedIndexChanged
      'Determine whether item is checked or not
      TextBox1.Text = BetterCheckedListBox1.Checked(BetterCheckedListBox1.SelectedIndex)
      TextBox2.Text = BetterCheckedListBox1.Text(BetterCheckedListBox1.SelectedIndex)
      TextBox3.Text = BetterCheckedListBox1.Value(BetterCheckedListBox1.SelectedIndex)
     End Sub
     Private Sub BetterCheckedListBox1_ItemCheck(ByVal _
            sender As Object, ByVal e As _
            System.Windows.Forms.ItemCheckEventArgs) _
            Handles BetterCheckedListBox1.ItemCheck
      TextBox1.Text = _
       BetterCheckedListBox1.Checked(BetterCheckedListBox1.SelectedIndex)
     End Sub
    End Class

    部署 确保创建的自定义控件是强命名的。为此,您必须首先生成一个密钥文件并告诉编译器使用它。 在Visual Studio命令提示符下运行以下命令生成一个密钥文件:复制Code

    sn -k C:\Better.snk

    然后,在自定义控件项目的AssemblyInfo.vb文件中添加以下内容作为第一行(在导入下)。隐藏,复制Code

    <Assembly: AssemblyKeyFileAttribute("Better.snk")>

    就是这样。BetterCheckedListBox控件现在可以轻松地部署到全局程序集缓存中。 本文转载于:http://www.diyabc.com/frontweb/news363.html

  • 相关阅读:
    ARCGIS JAVASCRIPT API (3.2)部署
    WINFORM 只能运行一个实例问题
    iOS 版本号
    同步和异步的区别
    简单的手机号判断
    "_inflateEnd", referenced from "_inflateInit_"等。这时需要在工程中加入libz.dlib 文件
    iOS 实现打电话
    assign retain copy iOS
    iOS 长按事件 UILongPressGestureRecognizer
    UITableView 滑动删除
  • 原文地址:https://www.cnblogs.com/Dincat/p/13443832.html
Copyright © 2011-2022 走看看