首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义DataGridViewColumn替换DataGridViewComboBoxColumn

自定义DataGridViewColumn替换DataGridViewComboBoxColumn
EN

Code Review用户
提问于 2015-11-05 15:06:52
回答 1查看 393关注 0票数 1

我试图用这段代码解决的问题很简单

我有一个巨大的数据集,我必须将它绑定到一个DataGridView

在该数据集中,我有一些列是列表的键,我必须从该列表中显示一个自定义属性。

DataGridViewComboBoxColumn中,取消共享行是一个很大的问题,在处理绑定源时会造成巨大的减速。

这是一项正在进行的工作(实际上是可行的)。

有什么东西不见了或者有什么红旗吗?

另请注意,此代码必须在净3.5下工作。

DataGridViewColumn:

代码语言:javascript
复制
Option Strict On
Option Explicit On

Imports System.ComponentModel
Imports System.Drawing.Design
Imports System.Reflection

Public Class DataGridViewTypeInfoColumn
    Inherits DataGridViewColumn

    Public Sub New()
        MyBase.New(New DataGridViewTypeInfoCell())
    End Sub

    Private _dataSource As Object
    Private _displayMember As String
    Private _valueMember As String

    Private _bindingDataSource As BindingSource
    Private _bindingDescriptorCollection As PropertyDescriptorCollection
    Private _valueMemberDescriptor As PropertyDescriptor
    Private _displayMemberDescriptor As PropertyDescriptor

    <DefaultValue(""),
     AttributeProvider(GetType(IListSource)),
     RefreshProperties(RefreshProperties.Repaint),
     Category("Data")>
    Public Property DataSource As Object
        Get
            Return _dataSource
        End Get
        Set(value As Object)
            CleanUp()
            _dataSource = value
        End Set
    End Property

    <DefaultValue(""),
     Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", GetType(UITypeEditor)),
     TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"),
     Category("Data"),
      Localizable(True)>
    Public Property DisplayMember() As String
        Get
            Return _displayMember
        End Get
        Set(value As String)
            _displayMember = value
        End Set
    End Property

    <DefaultValue(""),
     Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", GetType(UITypeEditor)),
     TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"),
     Category("Data")>
    Public Property ValueMember() As String
        Get
            Return _valueMember
        End Get
        Set(value As String)
            _valueMember = value
        End Set
    End Property

    Public Function GetValue(ByVal originalValue As Object) As Object
        Dim returnValue As Object

        Try
            If TypeOf originalValue Is String AndAlso originalValue IsNot Nothing Then
                originalValue = originalValue.ToString.Trim
            End If

            If _dataSource IsNot Nothing Then
                If _bindingDataSource Is Nothing Then
                    _bindingDataSource = DirectCast(_dataSource, BindingSource)
                End If

                If _bindingDescriptorCollection Is Nothing AndAlso _bindingDataSource.Current IsNot Nothing Then
                    _bindingDescriptorCollection = TypeDescriptor.GetProperties(_bindingDataSource.Current.GetType)
                    If _bindingDescriptorCollection IsNot Nothing Then
                        _valueMemberDescriptor = _bindingDescriptorCollection.Find(ValueMember, True)
                        _displayMemberDescriptor = _bindingDescriptorCollection.Find(DisplayMember, True)
                    End If
                End If
            End If

            If _valueMemberDescriptor IsNot Nothing AndAlso _displayMemberDescriptor IsNot Nothing Then
                For Each item In _bindingDataSource.List
                    returnValue = _valueMemberDescriptor.GetValue(item)

                    If originalValue.Equals(returnValue) Then
                        returnValue = _displayMemberDescriptor.GetValue(item)

                        Return returnValue
                    End If
                Next
            End If
        Catch ex As Exception

        End Try

        Return originalValue
    End Function

    Public Overrides Function Clone() As Object
        Dim myClone As DataGridViewTypeInfoColumn = DirectCast(MyBase.Clone, DataGridViewTypeInfoColumn)

        myClone.DataSource = DataSource
        myClone.DisplayMember = DisplayMember
        myClone.ValueMember = ValueMember

        Return myClone
    End Function

    Private Sub CleanUp()
        If _bindingDataSource IsNot Nothing Then
            _bindingDataSource.Dispose()
        End If
        _valueMemberDescriptor = Nothing
        _displayMemberDescriptor = Nothing
        _bindingDescriptorCollection = Nothing
        _bindingDataSource = Nothing
        _dataSource = Nothing
    End Sub

    Protected Overrides Sub Dispose(disposing As Boolean)
        CleanUp()
        MyBase.Dispose(disposing)
    End Sub
End Class

DataGridViewCell:

代码语言:javascript
复制
Option Strict On
Option Explicit On

Imports System.ComponentModel

Public Class DataGridViewTypeInfoCell
    Inherits DataGridViewTextBoxCell

    Protected Overrides Function GetFormattedValue(value As Object, rowIndex As Integer, ByRef cellStyle As DataGridViewCellStyle, valueTypeConverter As TypeConverter, formattedValueTypeConverter As TypeConverter, context As DataGridViewDataErrorContexts) As Object
        Dim formattedValue As Object = DirectCast(Me.OwningColumn, DataGridViewTypeInfoColumn).GetValue(value)

        Return MyBase.GetFormattedValue(formattedValue, rowIndex, cellStyle, valueTypeConverter, formattedValueTypeConverter, context)
    End Function
End Class
EN

回答 1

Code Review用户

发布于 2015-11-05 15:33:18

主要集中在这方面

公共函数GetValue(ByVal originalValue As Object)作为对象Dim returnValue作为对象尝试如果TypeOf originalValue是String AndAlso originalValue IsNot Nothing那么originalValue = originalValue.ToString.Trim结束如果_dataSource IsNot Nothing那么_bindingDataSource是空的则_bindingDataSource =DirectCast如果TypeDescriptor.GetProperties(_bindingDataSource.Current.GetType)是Nothing AndAlso _bindingDataSource.Current IsNot Nothing,那么_bindingDescriptorCollection = _bindingDescriptorCollection IsNot Nothing,_valueMemberDescriptor = _bindingDescriptorCollection.Find(ValueMember,True) _displayMemberDescriptor = _bindingDescriptorCollection.Find(DisplayMember,如果_valueMemberDescriptor IsNot Nothing AndAlso _displayMemberDescriptor IsNot,那么对于_bindingDataSource.List returnValue =_valueMemberDescriptor.GetValue(项目)中的每一项,如果originalValue.Equals( returnValue ),则returnValue=_displayMemberDescriptor.GetValue(条目)返回returnValue结束,如果下一个结束,如果捕获ex作为异常结束,尝试返回originalValue结束函数

  • 通过逆转_dataSource IsNot Nothing条件,您可以提前返回,这将为您节省一些水平空间。
  • 如果将_bindingDataSource设置为DataSource设置器,则可以在此处删除。
  • 如果你认为你可以安全地吞下任何例外,你应该说清楚你为什么要吞咽。或者至少给它添加一些日志。
  • 在组相关代码中添加一些垂直空间(新行)将提高可读性。

否则,代码看起来很干净,方法参数、局部变量和类的Option Explicit On和使用的名称都很好,并且遵循了网络命名准则。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/109891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档