Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在DataGridView custon列中处理单元格解析_C#_.net_Vb.net_Winforms_Datagridview - Fatal编程技术网

C# 在DataGridView custon列中处理单元格解析

C# 在DataGridView custon列中处理单元格解析,c#,.net,vb.net,winforms,datagridview,C#,.net,Vb.net,Winforms,Datagridview,我为DataGridView定义了一个自定义列,以十六进制显示值。它所做的只是格式化文本并指定字体 (由于VB.NET中的历史原因:-)) 为了处理输入,我在网格上为CellParsing事件定义了一个处理程序 Private Sub dgvValues_CellParsing(sender As Object, e As DataGridViewCellParsingEventArgs) Handles dgvValues.CellParsing If dgvValues.Col

我为DataGridView定义了一个自定义列,以十六进制显示值。它所做的只是格式化文本并指定字体

(由于VB.NET中的历史原因:-))

为了处理输入,我在网格上为CellParsing事件定义了一个处理程序

Private Sub dgvValues_CellParsing(sender As Object, e As DataGridViewCellParsingEventArgs) Handles dgvValues.CellParsing

  If     dgvValues.Columns(e.ColumnIndex).Name = "NewDAC" _
  OrElse dgvValues.Columns(e.ColumnIndex).Name = "NewOffset" _
  OrElse dgvValues.Columns(e.ColumnIndex).Name = "New80PercentValue" _
  Then

    If e IsNot Nothing AndAlso e.Value IsNot Nothing Then
      Try
        Dim InputString   As String = TryCast(e.Value, String)
        Dim newValue      As Int32  = TypeDescriptor.GetConverter(newValue).ConvertFrom(InputString)
        Dim bytes         As Byte() = BitConverter.GetBytes(newValue)

        If e.DesiredType.Equals(GetType(UInt16)) Then
          e.Value = BitConverter.ToUInt16 ( bytes, 0 )
        ElseIf e.DesiredType.Equals(GetType(Int16)) Then
          e.Value = BitConverter.ToInt16 ( bytes, 0 )
        ElseIf e.DesiredType.Equals(GetType(UInt32)) Then
          e.Value = BitConverter.ToUInt32 ( bytes, 0 )
        ElseIf e.DesiredType.Equals(GetType(Int32)) Then
          e.Value = newValue
        End If

        e.ParsingApplied = True
      Catch

      End Try
    End If

  End If

End Sub
这基本上是可行的,但我更愿意将单元解析逻辑完全封装在自定义列中

这样我就可以只选择列类型,一切都可以正常工作,而不需要在包含网格的表单中进行任何特殊处理

Private Sub dgvValues_CellParsing(sender As Object, e As DataGridViewCellParsingEventArgs) Handles dgvValues.CellParsing

  If     dgvValues.Columns(e.ColumnIndex).Name = "NewDAC" _
  OrElse dgvValues.Columns(e.ColumnIndex).Name = "NewOffset" _
  OrElse dgvValues.Columns(e.ColumnIndex).Name = "New80PercentValue" _
  Then

    If e IsNot Nothing AndAlso e.Value IsNot Nothing Then
      Try
        Dim InputString   As String = TryCast(e.Value, String)
        Dim newValue      As Int32  = TypeDescriptor.GetConverter(newValue).ConvertFrom(InputString)
        Dim bytes         As Byte() = BitConverter.GetBytes(newValue)

        If e.DesiredType.Equals(GetType(UInt16)) Then
          e.Value = BitConverter.ToUInt16 ( bytes, 0 )
        ElseIf e.DesiredType.Equals(GetType(Int16)) Then
          e.Value = BitConverter.ToInt16 ( bytes, 0 )
        ElseIf e.DesiredType.Equals(GetType(UInt32)) Then
          e.Value = BitConverter.ToUInt32 ( bytes, 0 )
        ElseIf e.DesiredType.Equals(GetType(Int32)) Then
          e.Value = newValue
        End If

        e.ParsingApplied = True
      Catch

      End Try
    End If

  End If

End Sub

有没有办法在自定义列(或单元格)类中处理单元格解析?

如果我正确理解了您的要求,
您需要在自定义列类中封装处理程序逻辑?。这样做是可行的,把sub放在类中,这样你的类应该看起来像这样

Public Class clsDgvHexColumn
  Inherits DataGridViewTextBoxColumn

  Private mFont             As System.Drawing.Font

  public sub New
    MyBase.CellTemplate = new clsDgvHexColumnCell
    mFont = New System.Drawing.Font ( "Consolas", 10 )
  End Sub

  Public Property Font As Font
    Get
      Return mFont
    End Get
    Set(ByVal value As Font)
      mFont = value
      Me.DefaultCellStyle.Font = mFont
    End Set
  End Property

Public Shared Sub Handler_CellParsing(sender As Object, e As DataGridViewCellParsingEventArgs)
      Dim dgv as Your_Type //This is the type of dgvValues (which is DataGridView) I suppose, Replace Your_Type appropriately
      dgv = CType(sender,Your_Type)
      If     dgv.Columns(e.ColumnIndex).Name = "NewDAC" _
      OrElse dgv.Columns(e.ColumnIndex).Name = "NewOffset" _
      OrElse dgv.Columns(e.ColumnIndex).Name = "New80PercentValue" _
      Then

    If e IsNot Nothing AndAlso e.Value IsNot Nothing Then
      Try
        Dim InputString   As String = TryCast(e.Value, String)
        Dim newValue      As Int32  = TypeDescriptor.GetConverter(newValue).ConvertFrom(InputString)
        Dim bytes         As Byte() = BitConverter.GetBytes(newValue)

        If e.DesiredType.Equals(GetType(UInt16)) Then
          e.Value = BitConverter.ToUInt16 ( bytes, 0 )
        ElseIf e.DesiredType.Equals(GetType(Int16)) Then
          e.Value = BitConverter.ToInt16 ( bytes, 0 )
        ElseIf e.DesiredType.Equals(GetType(UInt32)) Then
          e.Value = BitConverter.ToUInt32 ( bytes, 0 )
        ElseIf e.DesiredType.Equals(GetType(Int32)) Then
          e.Value = newValue
        End If

        e.ParsingApplied = True
      Catch

      End Try
    End If

  End If

End Sub
End Class
当您创建DataGridView或其他任何东西时,只需将事件处理程序添加到控件中,如下所示

AddHandler dgvValues.CellParsing , AddressOf clsDgvHexColumn.Handler_CellParsing

但是,我对您的目标的解释可能是错误的。

根据Ivan Stoev的建议,这是我新的自定义列定义:

Public Class clsDgvHexColumn
  Inherits DataGridViewTextBoxColumn

  Private mFont             As System.Drawing.Font

  public sub New
    MyBase.CellTemplate = new clsDgvHexColumnCell
    mFont = New System.Drawing.Font ( "Consolas", 10 )
  End Sub

  Public Property Font As Font
    Get
      Return mFont
    End Get
    Set(ByVal value As Font)
      mFont = value
      Me.DefaultCellStyle.Font = mFont
    End Set
  End Property

End Class

Public Class clsDgvHexColumnCell
  Inherits DataGridViewTextBoxCell

  Protected Overrides Function GetFormattedValue ( ByVal value                        As Object, _
                                                   ByVal rowIndex                     As Integer, _
                                                   ByRef cellStyle                    As System.Windows.Forms.DataGridViewCellStyle, _
                                                   ByVal valueTypeConverter           As System.ComponentModel.TypeConverter, _
                                                   ByVal formattedValueTypeConverter  As System.ComponentModel.TypeConverter, _
                                                   ByVal context                      As System.Windows.Forms.DataGridViewDataErrorContexts ) As Object
    Return String.Format ( "0x{0:X4}", value )
  End Function

  Public Overrides Function ParseFormattedValue ( ByVal formattedValue              As Object, 
                                                  ByVal cellStyle                   As DataGridViewCellStyle, 
                                                  ByVal formattedValueTypeConverter As TypeConverter, 
                                                  ByVal valueTypeConverter          As TypeConverter ) As Object

    Dim InputString As String = TryCast(formattedValue, String)
    Dim newValue    As Int32  = TypeDescriptor.GetConverter(newValue).ConvertFrom(InputString)
    Dim bytes       As Byte() = BitConverter.GetBytes(newValue)

    If ValueType.Equals(GetType(UInt16)) Then
      Return BitConverter.ToUInt16 ( bytes, 0 )
    ElseIf ValueType.Equals(GetType(Int16)) Then
      Return BitConverter.ToInt16 ( bytes, 0 )
    ElseIf ValueType.Equals(GetType(UInt32)) Then
      Return BitConverter.ToUInt32 ( bytes, 0 )
    ElseIf ValueType.Equals(GetType(Int32)) Then
      Return newValue
    Else
      Return newValue
    End If

  End Function

End Class

目前,这似乎符合我的要求。

我认为这就是解决方案。有没有办法获取绑定数据的类型(Int16、UInt16、Int32、UInt32)?如果没有,我可能会创建单独的列类型,HexColumnInt16、HexColumnUInt16、HexColumnInt32和HexColumnUInt32。属性(至少这是默认实现使用的:)谢谢,这很有效。如果我可以在自定义列类的代码中放置AddHandler调用,那就可以了。我必须想一想在哪里做这件事。此外,列检查还必须检查自身(而不是特定的命名列)。我想要的是选择列的类型,并且不需要表单中的其他自定义代码。