Capturing the ctrl+V in VB.NET combobox - vb.net

I am trying to remove the newline and replace with whitespace before pasting to comboBox as it ignores anything beyond a line. I am trying this:
If e.Modifiers = Keys.Control AndAlso e.KeyValue = Keys.V Then Then
Clipboard.SetText(Regex.Replace(Clipboard.GetText(TextDataFormat.UnicodeText), "\n", " "))
e.Handled = True
End If
I am performing this inside KeyDown event but it is able to capture either Ctrl or V but not both. I tried Capture CTRL+V or paste in a textbox in .NET and http://social.msdn.microsoft.com/Forums/windows/en-US/096540f4-4ad4-4d24-ae12-cfb3e1b246f3/interceptingoverriding-paste-behavior-on-combobox but no results as desired. May be there is something i am missing in my code. Please help me out.
I am getting the needed value with this Clipboard.GetText().Replace(vbCrLf, " ") when i debug but i am not able to set it. I tried using a variable to set it but even then no change. I also tried clearing the clipboard and then resetting with this variable holding the modified value.
I am using Winforms and i tried this but still no change to my clipboard:
Private Const WM_PASTE As Integer = &H302
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = WM_PASTE Then
Dim returnText As String = Nothing
If (Clipboard.ContainsText()) Then
returnText = Clipboard.GetText().Replace(vbCrLf, " ")
Clipboard.Clear()
Clipboard.SetText(returnText)
End If
End If
MyBase.WndProc(m)
End Sub

Handling keyboard only events for intercepting pasting doesn't solve the problem, because pasting can also be done using mouse or touch interface.
Thus, if you are using WPF, then simply add the DataObject.Pasting event handler to your ComboBox, so definition of the control in XAML will look like:
<ComboBox Name="comboBox1" IsEditable="true" DataObject.Pasting="comboBox1_Pasting" ... />
And, finally, in your code handle it as (I'm adding a method here to the code-behind, which is not as nice, as using commands):
private void comboBox1_Pasting(object sender, DataObjectPastingEventArgs e)
{
// modify the clipboard content here
}
If you're using WinForms, then look here: hook on default “Paste” event of WinForms TextBox control

This piece of code worked for me:
Private Const WM_PASTE As Integer = &H302
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
If keyData = (Keys.Control Or Keys.V) Or msg.Msg = WM_PASTE Then
If (Clipboard.ContainsText()) Then
Clipboard.SetText(Clipboard.GetText().Replace(vbCrLf, " "))
End If
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function

Use the keydown event and alter the clipboard like this
Private Sub ComboBox1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyDown
If e.KeyCode = Keys.V AndAlso (e.Modifiers And Keys.Control) <> 0 Then
My.Computer.Clipboard.SetText(My.Computer.Clipboard.GetText().Replace(vbCrLf, " "))
End If
End Sub
But this example is going to alter the clipboard contents. Modify it to paste or insert yourself as you wish

Related

How to clear all contents of textbox when spacebar is pressed? VB.Net

I'm creating a simple typing test program.
I want the space bar to trigger checking if the typed word is correct, then clear the contents of the textbox.
What happens here is the first typed word will work and be counted when the space bar is pressed and the typed word will be cleared, but the space character still remains and so the next typed word will contain a space char and will be read wrong.
I tried interchanging where the txtInput.Clear() should be placed but results in the same problem.
Private Sub txtInput_TextChanged(sender As Object, e As KeyEventArgs) Handles txtInput.KeyDown
If e.KeyValue = Keys.Space Then
Space()
End If
End Sub
Public Function Space()
If txtInput.Text = txtWord.Text Then
ctr = CInt(txtWord.TextLength)
charTotal = charTotal + ctr
lblScore.Text = charTotal.ToString
End If
txtInput.Clear()
txtWord.Text = rdmWord()
End Function
In KewDown Event the value of TextBox isnot setted yet. So, use KeyUp Event as the code below shows
Private Sub txtInput_KeyUp(sender As Object, e As KeyEventArgs) Handles txtInput.KeyUp
If e.KeyValue = Keys.Space Then
Space()
End If
End Sub
You could also override ProcessCmdKey and trap the spacebar there:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
If keyData = Keys.Space Then
If Me.ActiveControl Is txtInput Then
Space()
Return True ' suppress space
End If
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
If you want to allow space or enter, then change to:
If keyData = Keys.Space Or keyData = Keys.Enter Then

Why DateTimePicker won't trigger keyDown and KeyPress events with the tab key?

Fellows, I am having this problem - the DateTimePicker won't trigger KeyDown and KeyPress events with the tab key (other keys are working fine, and the keyUp event as well, although it triggers after "arriving" at the DateTimePicker after pressing tab at the previous control focused). I'm using .net 4.6.1, Visual Basic and VS 2017.
What I'm trying to do -> Go to month and year directly on DateTimePicker in C# (Go to month and year directly on DateTimePicker)
Code I'm using:
Private Sub DateTimePicker1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DateTimePicker1.KeyDown
If e.KeyCode = Keys.Tab Then
e.Handled = True
MsgBox("TAB DOWN")
End If
End Sub
Private Sub DateTimePicker1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles DateTimePicker1.KeyPress
e.Handled = True
MsgBox("tab press")
End Sub
Private Sub DateTimePicker1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DateTimePicker1.KeyUp
If e.KeyCode = Keys.Tab Then
MsgBox("TAB UP")
e.Handled = True
End If
End Sub
Any clues?
The Tab key is used for navigation. Moving the focus from one control to another. So your KeyDown event handler can never see it, the keystroke is intercepted and used before that. You could subscribe the PreviewKeyDown event and set the e.IsInputKey = true as a workaround, check the MSDN sample code in the linked article for code.
But it is the wrong event to use anyway, you'd still want this to work when the user changes focus with the mouse instead of the keyboard. So use the Enter event instead.
Do beware that both approaches have the same problem, the focus might already be on the month part from previous usage of the control so now your code will incorrectly move it to the year part. And you can't find out what part has the focus, that is up a creek without a good paddle. A very ugly workaround for that is to change the Format property, and back, that forces the control to re-create the control window and that always resets the focus. Use BeginInvoke() to run that code. Perhaps more constructively, consider to just not display the day if you are only interested in month+year, CustomFormat property.
Sample code that implements the focus hack:
Private Sub DateTimePicker1_Enter(sender As Object, e As EventArgs) Handles DateTimePicker1.Enter
Me.BeginInvoke(
New Action(Sub()
'' Hack to reset focus
DateTimePicker1.Format = DateTimePickerFormat.Long
DateTimePicker1.Format = DateTimePickerFormat.Short
DateTimePicker1.Focus()
SendKeys.Send("{Right}")
End Sub))
End Sub
It's not the right answer to this question, although it helps as well. If you want to just make the tab behave as the right key when inside a DateTimePicker, a good (sketchy) way to do is:
Private i = 2
Protected Overrides Function ProcessTabKey(ByVal forward As Boolean) As Boolean
Dim ctl As Control = Me.ActiveControl
If ctl IsNot Nothing AndAlso TypeOf ctl Is DateTimePicker And i <> 0 Then
SendKeys.Send("{Right}")
i -= 1
Return True
End If
i = 2
Return MyBase.ProcessTabKey(forward)
End Function
You need to override ProcessCmdKey function
Private isTab As Boolean = False
Private isShiftTab As Boolean = False
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
If keyData = Keys.Tab Then
isTab = True
'Do something with it.
Else
isTab = False
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function

Set Focus to a text box when F1 is pressed

I have been trying to get this to work but it's doing my head in, wondered if you experts can help me out.
On my form I would like to set focus to a TextBox when I press F1 on the keyboard, I have the code written but somehow it does not work when I press F1. What am I doing wrong? I have also set keypreview to true.
The code here:
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If e.KeyData = Keys.F1 Then
txtemployeeno.Focus()
End If
End Sub
The problem is that your KeyUp event isn't firing because the form doesn't technically have input focus (though it may be activated). If you wish to use the KeyPreview property, you need to use the KeyPress event instead of KeyUp.
Alternatively, you could always override the ProcessCmdKey function. Just add the following method to your form's code:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
If keyData = Keys.F1 Then
txtemployeeno.Focus()
Return True
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function

How to prevent special characters in datagridview using vb.net

I have a windows forms vb.net program that uses a datagridview. I'm trying to find a way to prevent a user from entering special characters (e.g. $,#,!,#,%,^,&) in my datagridview. When the user inputs a special character I have an approprioate message box appear explaining their mistake, then I provide them a default value. I have everything working except a way to prevent the special character or symbols. I'm thinking something like this has to work, but I can't seem to find any way of preventing this sort of entry:
If (columnindex = 0) Then 'checking value for column 1 only
Dim cellString = DataGridView1.Rows(rowindex).Cells(columnindex).value
If cellString String.IsSymbol(cellString) = true Then
MessageBox.Show("Special Characters Not Allowed")
End If
DataGridView1.Rows(rowindex).Cells(columnindex).value = "Default Value"
Exit Sub
End If
You can use the EditingControlShowing event to register a KeyPress function for the input box.
Private Sub YourDataGridView_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles YourDataGridView.EditingControlShowing
Try
RemoveHandler e.Control.KeyPress, AddressOf YourFunctionToPreventSpecialCharacters
Catch ex As Exception
End Try
If Me.dgvTableViewer.CurrentCell.ColumnIndex = YourDataGridView.Columns("YourColumn").Index Then
AddHandler e.Control.KeyPress, AddressOf YourFunctionToPreventSpecialCharacters
End If
End Sub
Try and Put this in the DataGridView's keydown event:
Private Sub DataGridView1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown
Select Case e.KeyCode
Case Keys.D0 To Keys.D9 And e.Shift
MsgBox("NOPE.")
e.SuppressKeyPress = True
End Select
End Sub
That basically checks if the keypress is coming from the 0-9 keys on your computer and also if you are holding the SHIFT Key. If it is then it displays a Msgbox and Suppresses the keypress. This blocks chars on your keyboard's 0-9 shift !##$%^&*(). You can edit this like
Case Keys.A
e.Suppress ...
Msgbox ... etc

How to embed a Console in a Windows Form application?

I'm trying to build a Text Adventure game in VB.net, just like the days of old. The obvious choice would be a Console application, however, I have decided on a Windows Form because I am hoping to include interactive buttons and pictures. Currently, I have already got on my form a picture box and a Rich Text Box. I was hoping that with the Rich Text Box I could achieve something that worked in the same way as a console. Alas, my efforts are futile. Everything I have tried has failed, including: reading Rich_Text_Box.Text and Rich_Text_Box_KeyUp with an if statement for enter being pressed to call the procedure for an enter button.
I was wondering if there was any way to include a Console with standard Console.WriteLine and Console.ReadLine capabilities inside of my Form? This would very much shorten my task and streamline the whole process.
Any ideas?
You could use not one but two Textboxes for your purpose. tbOutput and tbInput. tbOutput would be Multiline and ReadOnly whereas tbInput would be single line, not readonly and placed beneath tbOutput. Then to process inputs you could do something like:
Private Sub Output(s As String)
If s <> "" Then
tbOutput.AppendText(vbCrLf & ">> " & s)
End If
End Sub
Private Sub tbInput_KeyDown(sender As Object, e As KeyEventArgs) Handles tbInput.KeyDown
If e.KeyCode = Keys.Enter Then
If tbInput.Text <> "" Then
Output(tbInput.Text)
' Handle input value
tbInput.Text = ""
End If
End If
End Sub
At the 'Handle input value you would check the user input and handle it according to your needs. Use Lucida Console font in bold in gray and black background for style :-)
Sure, a RichTextBox can be used to emulate a console. Some surgery is required to avoid the user from making it malfunction as a console. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form. Subscribe the InputChanged event to detect when the user presses the Enter key, the Input property gives you the typed text. Use the Write() or WriteLine() methods to add text.
Imports System.Windows.Forms
Public Class RichConsole
Inherits RichTextBox
Public Event InputChanged As EventHandler
Public ReadOnly Property Input() As String
Get
Return Me.Text.Substring(InputStart).Replace(vbLf, "")
End Get
End Property
Public Sub Write(txt As String)
Me.AppendText(txt)
InputStart = Me.SelectionStart
End Sub
Public Sub WriteLine(txt As String)
Write(txt & vbLf)
End Sub
Private InputStart As Integer
Protected Overrides Function ProcessCmdKey(ByRef m As Message, keyData As Keys) As Boolean
'' Defeat backspace
If (keyData = Keys.Back OrElse keyData = Keys.Left) AndAlso InputStart = Me.SelectionStart Then Return True
'' Defeat up/down cursor keys
If keyData = Keys.Up OrElse keyData = Keys.Down Then Return True
'' Detect Enter key
If keyData = Keys.[Return] Then
Me.AppendText(vbLf)
RaiseEvent InputChanged(Me, EventArgs.Empty)
InputStart = Me.SelectionStart
Return True
End If
Return MyBase.ProcessCmdKey(m, keyData)
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
'' Defeat the mouse
If m.Msg >= &H200 AndAlso m.Msg <= &H209 Then Return
MyBase.WndProc(m)
End Sub
End Class