Question

I'm using the following code (based on devexpress help fora) to prevent the user to give in more then 48 characters a line in a MemoEdit

Private Sub txtAuthors_EditValueChanging(sender As System.Object, e As DevExpress.XtraEditors.Controls.ChangingEventArgs) Handles txtAuthors.EditValueChanging
    If e.NewValue Is Nothing Then
        'No Value found in memoEditor
        Return
    End If
    'Max lenght of textbox
    Dim maxLength As Integer = 48
    Dim edit As DevExpress.XtraEditors.MemoEdit = TryCast(sender, DevExpress.XtraEditors.MemoEdit)
    For Each str As String In edit.Lines
        If str.Length > maxLength Then
            e.Cancel = True
            Return
        End If
    Next str
End Sub

This function prevents the insertion of String with more then 48 characters. But what I actually wish to achieve is the following:

My Goal: If the user enters a new string (using Ctrl + V/Paste) with more than 48 chars. it should not prevent all the data from being entered. The control should except the first 48 chars en ditch the rest. How to achieve this behavior. I've tried to manipulate e.NewValue but to no avail...

Remark about the Lines-property:

You are not able to use the Lines property to change a particular array's element
directly. Instead, you should read the Lines property to get the array, change 
the required array's element and then assign the array back to Lines.

Note: Ive read this (Limit the input length of a DevExpress TextEdit and MemoEdit controls) but it didn't help

Note 2: The input being given inside the MemoEdit may vary from ordinary user-input (pressing any key or Ctrl + V) to computerbased-input coming from a WCF-Service

Was it helpful?

Solution 2

After some trial & errors (with some infinite loops added to the mix), I've managed to find a good (not perfect) solution. I Hope the following code might be of some use to anyone.

 Public Sub EditValueChanged(sender As System.Object, e As System.EventArgs) Handles txt.EditValueChanged

    Dim edit As DevExpress.XtraEditors.MemoEdit = TryCast(sender, DevExpress.XtraEditors.MemoEdit)
    'Take copy of the array
    Dim myStringArrayCopy As String() = control.Lines
    Dim hasEdits As Boolean = False

    For Each str As String In myStringArrayCopy
        If str.Length > maxCharCount Then
            Dim indexString As Integer = Array.IndexOf(myStringArrayCopy, str)
            myStringArrayCopy(indexString) = str.Substring(0, 47)
            hasEdits = True
        End If
    Next str

    If (hasEdits) Then
        control.Lines = myStringArrayCopy
        control.Refresh()
    End If
End Sub

I have a couple of remarks to this code.

Remark 1: Use EditValueChanged instead of EditValueChanging. It makes more sense to modify the textbox after the edit has been made instead of in the middle.

Remark 2: If an edit has been made with more then 48 chars. Then the string will be shortened but the cursor will be placed on the firstline (this is a multiline txt)

Remark 3: Don't forget the refresh(). Otherwise the changes being made won't be visible to the user.

OTHER TIPS

Using a standard winform textbox this can be achieved by handling the KeyDown event, look for Ctrl + V keys and check the Cliboard text.

Private Sub txtAuthors_KeyDown(sender As Object, e As KeyEventArgs) Handles txtAuthors.KeyDown
    If ((e.Modifiers = Keys.Control) AndAlso (e.KeyCode = Keys.V)) Then
        Dim text As String = My.Computer.Clipboard.GetText()
        If (text.Length > 48) Then
            My.Computer.Clipboard.SetText(text.Substring(0, 48))
        End If
    End If
End Sub

Note: I do not have devexpress installed, so I cannot guarantee this will work for the MemoEdit control.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top