65.9K
CodeProject 正在变化。 阅读更多。
Home

带复选框的列表框集合编辑器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.22/5 (8投票s)

2008年2月23日

CPOL

1分钟阅读

viewsIcon

66169

downloadIcon

1324

在属性网格中实现一个自定义的、带复选框的列表框编辑器。

引言

这段代码演示了如何创建一个自定义属性编辑器,尤其适用于键/值对信息。它实现了 IWindowsFormsEditorServiceUITypeEditorEditStyle,这些接口用于创建自定义属性网格控件。

背景

有几个现有项目演示了如何创建一个自定义 ListBox,但我没有找到任何演示带复选框的 ListBox 的项目,所以我自己编写了一个。

Using the Code

My.PropertyGridControls.CheckedListBoxEditor 自定义属性编辑器与绑定到属性网格的自定义属性类一起使用。



Imports System
Imports System.ComponentModel
Imports System.Windows.Forms.Design
Imports System.Windows.Forms
Imports System.Collections.Specialized

Namespace My.PropertyGridControls

    #Region "CheckedListBoxEditor"
    ''' <summary>
    ''' The control displayed in the property grid
    ''' </summary>
    ''' <remarks></remarks>
    Public Class CheckedListBoxEditor

        ''' <summary>
        ''' The default text displayed in the property grid "value" column
        ''' </summary>
        ''' <remarks></remarks>
        Private _strValue As String = "(Collection)"

        ''' <summary>
        ''' Creates a custom property editor using the CheckedListBoxEditor class
        ''' as the UITypeEditor
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        <Description("This property contains the checked ListBox collection."), _
            EditorAttribute(GetType(CheckedListBoxUITypeEditor), _
                GetType(System.Drawing.Design.UITypeEditor))> _
            Public Property CheckedListBoxCollectionProperty() As String
            Get
                Return _strValue
            End Get
            Set(ByVal value As String)
                _strValue = "(Collection)"
            End Set
        End Property

    End Class
    #End Region

    #Region "CheckedListBoxUITypeEditor"

    ''' <summary>
    ''' Custom, editable checked ListBox control
    ''' </summary>
    ''' <remarks>This demo loads a comma-delimited string collection of URLs
    ''' and boolean values to set the checked state for each item.</remarks>
    Public Class CheckedListBoxUITypeEditor
        Inherits System.Drawing.Design.UITypeEditor
        Public WithEvents cbx As New CheckedListBox
        Private es As IWindowsFormsEditorService

        ''' <summary>
        ''' Override the UITypeEditorEditStyle to return the editor style:
        ''' drop-down, modal, or none
        ''' </summary>
        ''' <param name="context"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overloads Overrides Function GetEditStyle_
            (ByVal context As System.ComponentModel.ITypeDescriptorContext) _
                As System.Drawing.Design.UITypeEditorEditStyle

            'returns the editor style:  drop-down, modal, or none
            Return System.Drawing.Design.UITypeEditorEditStyle.DropDown

        End Function

        ''' <summary>
        ''' Override whether or not the ListBox control should be resizable
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overloads Overrides ReadOnly Property IsDropDownResizable() As Boolean
            Get
                'if set to true, adds a grip to the lower left portion of the ListBox,
                'which makes the ListBox resizable as run time
                Return True

            End Get
        End Property

        ''' <summary>
        ''' Override the default method for editing values in the ListBox
        ''' </summary>
        ''' <param name="context"></param>
        ''' <param name="provider"></param>
        ''' <param name="value"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overloads Overrides Function EditValue_
            (ByVal context As System.ComponentModel.ITypeDescriptorContext, _
            ByVal provider As System.IServiceProvider, ByVal value As Object) As Object

            'instantiate the custom property editor service provider
            es = DirectCast(provider.GetService(GetType(IWindowsFormsEditorService)), _
                IWindowsFormsEditorService)

            If es IsNot Nothing Then

                'load the ListBox items
                LoadListBoxItems()

                'sort the items
                cbx.Sorted = True

                'show the control
                es.DropDownControl(cbx)

            End If

            'ensure function returns a value on all code paths
            Return Nothing

        End Function

        ''' <summary>
        ''' Save the ListBox key/value pairs to My.Settings.UrlList
        ''' </summary>
        ''' <param name="sender"></param>
        ''' <param name="e"></param>
        ''' <remarks></remarks>
        Private Sub bx_Leave(ByVal sender As Object, ByVal e As System.EventArgs) _
                Handles cbx.Leave
            'clear the old list
            My.Settings.UrlsList.Clear()

            With cbx
                'load the ListBox key/value pairs
                For i As Integer = 0 To .Items.Count - 1

                    Dim txt As String = .Items(i).ToString
                    Dim chk As String = .GetItemChecked(i).ToString

                    'concatenate the key/value pair
                    Dim combined As String = LCase(txt) & "," & LCase(chk)

                    If .Items(i).ToString IsNot "" Then

                        'add the concatenated string to the "UrlsList" string collection
                        My.Settings.UrlsList.Add(combined)

                    End If
                Next
            End With
            'save the config file
            My.Settings.Save()
        End Sub

        ''' <summary>
        ''' Loads My.Settings.UrlList comma-delimited string collection
        ''' into the custom collection editor.
        ''' </summary>
        ''' <remarks></remarks>
        Private Sub LoadListBoxItems()
            'create an array list
            Dim a As New ArrayList

            'load the config file "UrlsList" string collection into the array
            For Each s As String In My.Settings.UrlsList

                'split the URL from the checked value
                a.Add(Split(s, ","))

            Next

            'create a hashtable, so we can refer to the items in a key/value pair format
            Dim h As New Hashtable

            'load the array into the hashtable
            For i As Integer = 0 To a.Count - 1

                'add the first array item as the key, the second as the value
                h.Add(CType(a.Item(i), Array).GetValue(0).ToString, _
                    CType(a.Item(i), Array).GetValue(1).ToString)

            Next

            'dispose of the array list
            a = Nothing

            'clear the ListBox items
            cbx.Items.Clear()

            'index the hashtable
            For Each de As DictionaryEntry In h

                'add the key/value pairs to the ListBox
                cbx.Items.Add(de.Key, CBool(de.Value))

            Next

            'dispose of the collection
            h = Nothing

        End Sub

    End Class
    #End Region

End Namespace

app.config 设置文件中的 StringCollection 加载 ListBox 中显示的项目。My.Settings.UrlsList 项目存储为逗号分隔的键/值对。

<userSettings>
    <CheckedListBoxCollectionEditor.My.MySettings>
        <setting name="UrlsList" serializeAs="Xml">
            <value>
                <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                    <string>http://www.thefreedictionary.com/,true</string>
                    <string>http://medical-dictionary.thefreedictionary.com/,
                        true</string>
                    <string>http://legal-dictionary.thefreedictionary.com/,true</string>
                    <string>http://financial-dictionary.thefreedictionary.com/,
                        true</string>
                    <string>http://acronyms.thefreedictionary.com/,true</string>
                    <string>http://idioms.thefreedictionary.com/,true</string>
                    <string>http://encyclopedia2.thefreedictionary.com/,true</string>
                    <string>http://encyclopedia.thefreedictionary.com/,true</string>
                    <string>http://www.m-w.com/dictionary/,true</string>
                    <string>http://www.freedictionary.org/search/,true</string>
                    <string>http://www.yourdictionary.com/,true</string>
                    <string>http://en.wikipedia.org/wiki/,true</string>
                </ArrayOfString>
            </value>
        </setting>
    </CheckedListBoxCollectionEditor.My.MySettings>
</userSettings>

如何使用该控件

  • 创建一个窗体
  • 添加一个属性网格
  • 实例化自定义属性编辑器,然后
  • 将其绑定到属性网格

请记住相应地更改 My.Settings.UrlsList 中的值。您也可以用您自己的 ListBox 项目加载函数替换 LoadListBoxItems()

''' <summary>
''' Sample form with a property grid whose selected object is the custom ListBox editor
''' </summary>
''' <remarks></remarks>
Public Class Form1

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

        'create the custom checked ListBox editor
        Dim c As New My.PropertyGridControls.CheckedListBoxEditor

        'bind it to the property grid
        Me.PropertyGrid1.SelectedObject = c
    End Sub
End Class


通过重写 IsDropDownResizable() 属性,使 ListBox 可调整大小,该属性在演示中设置为 True

''' <summary>
''' Override whether or not the ListBox control should be resizable
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Overloads Overrides ReadOnly Property IsDropDownResizable() As Boolean
    Get

        Return True

    End Get
End Property


如果您更喜欢不可调整大小的 ListBox,只需将 IsDropDownResizable() 更改为 False 即可。

''' <summary>
''' Override whether or not the ListBox control should be resizable
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Overloads Overrides ReadOnly Property IsDropDownResizable() As Boolean
    Get
        'if set to true, adds a grip to the lower left portion of the ListBox,
        'which makes the ListBox resizable as run time
        Return False

    End Get
End Property


待办事项

  • 允许就地编辑文本字符串
  • ListBox 的底部添加自定义“添加记录”控件

历史

  • 首次发布
© . All rights reserved.