How do I (elegantly) transpose textbox over label at specific part of string?

前端 未结 10 431
谎友^
谎友^ 2020-12-16 11:54

I\'ll be feeding a number of strings into labels on a Windows Form (I don\'t use these a lot). The strings will be similar to the following:

\"The qui

10条回答
  •  时光取名叫无心
    2020-12-16 12:36

    Consider using a combination of a DataGridView and a Masked Cell column.

    On Edit Control Showing, you would change the mask of that particular row.

    Here's some code usage example that includes the grid and the unique masking for each row.

    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            Dim mec As New MaskedEditColumn
            mec.Mask = ""
            mec.DataPropertyName = "Data"
            Me.DataGridView1.Columns.Add(mec)
    
    
            Dim tbl As New Data.DataTable
            tbl.Columns.Add("Data")
            tbl.Columns.Add("Mask")
            tbl.Rows.Add(New Object() {"The quick brown fox j   ed over the lazy hound", "The quick brown fox jaaaed over the l\azy hound"})
            tbl.Rows.Add(New Object() {"    quick brown fox j   ed over the lazy hound", "aaa quick brown fox jaaaed over the l\azy hound"})
            tbl.Rows.Add(New Object() {"The       brown fox j   ed over the lazy hound", "The aaaaa brown fox jaaaed over the l\azy hound"})
            Me.DataGridView1.AutoGenerateColumns = False
            Me.DataGridView1.DataSource = tbl
        End Sub
    
        Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    
            If e.Control.GetType().Equals(GetType(MaskedEditingControl)) Then
    
                Dim mec As MaskedEditingControl = e.Control
                Dim row As DataGridViewRow = Me.DataGridView1.CurrentRow
                mec.Mask = row.DataBoundItem("Mask")
    
            End If
    
        End Sub
    End Class
    

    And the grid column, sourced from here: http://www.vb-tips.com/MaskedEditColumn.aspx

    Public Class MaskedEditColumn
        Inherits DataGridViewColumn
        Public Sub New()
            MyBase.New(New MaskedEditCell())
        End Sub
        Public Overrides Property CellTemplate() As DataGridViewCell
            Get
                Return MyBase.CellTemplate
            End Get
            Set(ByVal value As DataGridViewCell)
    
                ' Ensure that the cell used for the template is a CalendarCell.
                If Not (value Is Nothing) AndAlso
                    Not value.GetType().IsAssignableFrom(GetType(MaskedEditCell)) _
                    Then
                    Throw New InvalidCastException("Must be a MaskedEditCell")
                End If
                MyBase.CellTemplate = value
            End Set
        End Property
        Private m_strMask As String
        Public Property Mask() As String
            Get
                Return m_strMask
            End Get
            Set(ByVal value As String)
                m_strMask = value
            End Set
        End Property
        Private m_tyValidatingType As Type
        Public Property ValidatingType() As Type
            Get
                Return m_tyValidatingType
            End Get
            Set(ByVal value As Type)
                m_tyValidatingType = value
            End Set
        End Property
        Private m_cPromptChar As Char = "_"c
        Public Property PromptChar() As Char
            Get
                Return m_cPromptChar
            End Get
            Set(ByVal value As Char)
                m_cPromptChar = value
            End Set
        End Property
        Private ReadOnly Property MaskedEditCellTemplate() As MaskedEditCell
            Get
                Return TryCast(Me.CellTemplate, MaskedEditCell)
            End Get
        End Property
    End Class
    Public Class MaskedEditCell
        Inherits DataGridViewTextBoxCell
        Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer,
            ByVal initialFormattedValue As Object,
            ByVal dataGridViewCellStyle As DataGridViewCellStyle)
            ' Set the value of the editing control to the current cell value.
            MyBase.InitializeEditingControl(rowIndex, initialFormattedValue,
                dataGridViewCellStyle)
            Dim mecol As MaskedEditColumn = DirectCast(OwningColumn, MaskedEditColumn)
            Dim ctl As MaskedEditingControl =
                CType(DataGridView.EditingControl, MaskedEditingControl)
            Try
                ctl.Text = Me.Value.ToString
            Catch
                ctl.Text = ""
            End Try
            ctl.Mask = mecol.Mask
            ctl.PromptChar = mecol.PromptChar
            ctl.ValidatingType = mecol.ValidatingType
        End Sub
        Public Overrides ReadOnly Property EditType() As Type
            Get
                ' Return the type of the editing contol that CalendarCell uses.
                Return GetType(MaskedEditingControl)
            End Get
        End Property
        Public Overrides ReadOnly Property ValueType() As Type
            Get
                ' Return the type of the value that CalendarCell contains.
                Return GetType(String)
            End Get
        End Property
        Public Overrides ReadOnly Property DefaultNewRowValue() As Object
            Get
                ' Use the current date and time as the default value.
                Return ""
            End Get
        End Property
        Protected Overrides Sub Paint(ByVal graphics As System.Drawing.Graphics, ByVal clipBounds As System.Drawing.Rectangle, ByVal cellBounds As System.Drawing.Rectangle, ByVal rowIndex As Integer, ByVal cellState As System.Windows.Forms.DataGridViewElementStates, ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal advancedBorderStyle As System.Windows.Forms.DataGridViewAdvancedBorderStyle, ByVal paintParts As System.Windows.Forms.DataGridViewPaintParts)
            MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
        End Sub
    End Class
    Class MaskedEditingControl
        Inherits MaskedTextBox
        Implements IDataGridViewEditingControl
        Private dataGridViewControl As DataGridView
        Private valueIsChanged As Boolean = False
        Private rowIndexNum As Integer
        Public Property EditingControlFormattedValue() As Object _
            Implements IDataGridViewEditingControl.EditingControlFormattedValue
            Get
                Return Me.Text
            End Get
            Set(ByVal value As Object)
                Me.Text = value.ToString
            End Set
        End Property
        Public Function EditingControlWantsInputKey(ByVal key As Keys,
               ByVal dataGridViewWantsInputKey As Boolean) As Boolean _
               Implements IDataGridViewEditingControl.EditingControlWantsInputKey
            Return True
        End Function
        Public Function GetEditingControlFormattedValue(ByVal context _
            As DataGridViewDataErrorContexts) As Object _
            Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
            Return Me.Text
        End Function
        Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As _
            DataGridViewCellStyle) _
            Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
    
            Me.Font = dataGridViewCellStyle.Font
            Me.ForeColor = dataGridViewCellStyle.ForeColor
            Me.BackColor = dataGridViewCellStyle.BackColor
        End Sub
        Public Property EditingControlRowIndex() As Integer _
            Implements IDataGridViewEditingControl.EditingControlRowIndex
            Get
                Return rowIndexNum
            End Get
            Set(ByVal value As Integer)
                rowIndexNum = value
            End Set
        End Property
        Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) _
            Implements IDataGridViewEditingControl.PrepareEditingControlForEdit
            ' No preparation needs to be done.
        End Sub
        Public ReadOnly Property RepositionEditingControlOnValueChange() _
            As Boolean Implements _
            IDataGridViewEditingControl.RepositionEditingControlOnValueChange
            Get
                Return False
            End Get
        End Property
        Public Property EditingControlDataGridView() As DataGridView _
            Implements IDataGridViewEditingControl.EditingControlDataGridView
            Get
                Return dataGridViewControl
            End Get
            Set(ByVal value As DataGridView)
                dataGridViewControl = value
            End Set
        End Property
    
        Public Property EditingControlValueChanged() As Boolean _
            Implements IDataGridViewEditingControl.EditingControlValueChanged
            Get
                Return valueIsChanged
            End Get
            Set(ByVal value As Boolean)
                valueIsChanged = value
            End Set
        End Property
        Public ReadOnly Property EditingControlCursor() As Cursor _
            Implements IDataGridViewEditingControl.EditingPanelCursor
            Get
                Return MyBase.Cursor
            End Get
        End Property
        Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
            ' Notify the DataGridView that the contents of the cell have changed.
            valueIsChanged = True
            Me.EditingControlDataGridView.NotifyCurrentCellDirty(True)
            MyBase.OnTextChanged(e)
        End Sub
    End Class
    

提交回复
热议问题