2017-07-21 9 views
0

DataGridViewのカスタム列を定義して、値を16進数で表示しました。テキストの書式を設定してフォントを指定するだけです。私は、グリッド上のCellParsingイベントのハンドラを定義した入力を処理するには(VB.NETの:-)の歴史的な理由から)DataGridViewキャッシュ列のハンドルセルの解析

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 

End Class 

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 

これは基本的に動作しますが、私は非常に完全にカスタム列内のロジックを解析し、細胞をカプセル化することを好むだろう。

このようにして、グリッドを含むフォームで特別な処理を行うことなく、すべてのカラムタイプを選択できます。

カスタム列(またはセル)クラス内でCellParsingを処理する方法はありますか?

+1

オーバーライド[ 'ParseFormattedValue'](https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcell.parseformattedvalue(V = vs.110).aspxの) –

+0

私はそれがあると思いますソリューション。バインドされたデータ(Int16、UInt16、Int32、UInt32)の型を取得する方法はありますか?もしそうでなければ、おそらくHexColumnInt16、HexColumnUInt16、HexColumnInt32、HexColumnUInt32のような別々の列型を作るでしょう。 –

+1

['ValueType'](https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcell.valuetype(v = vs.110).aspx)プロパティ(少なくともこれはデフォルトの実装では: –

答えて

0

私があなたの要求を正しく理解していれば、You need to encapsulate the handler logic inside the custom column class?そして、このようなものが可能になり、あなたのクラスは、この

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 

しかし、あなたの目標について私の解釈が間違っているかもしれません。

+0

カスタム列クラスのコードにAddHandler呼び出しを配置できれば問題ありません。私はそれをどこにするかを考えなければならないだろう。また、列チェックでは、特定の名前付き列ではなく、それ自体をチェックする必要があります。私が欲しいのは、列のタイプを選択し、フォーム内に他のカスタムコードを必要としないことです。 –

1

イワン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 

、これは私が望んでやっているようです。