Remove previous selection highlighting in RichTextBox without scrolling - vb.net

I have a form with a RichTextBox (RTB) and a listBox.
When the end user selects an item in the listbox, any matched text in the RTB is highlighted (full code removed for brevity).
re = New Regex(txtToFind)
For Each m In re.Matches(rtbMain.Text)
rtbMain.[Select](m.Index, m.Length)
rtbMain.SelectionColor = Color.White
rtbMain.SelectionBackColor = System.Drawing.SystemColors.Highlight
Next
When the user left mouse clicks in the RTB I want the previously highlighted text to be cleared. This is the standard windows behaviour - If you manually select some text in an RTB with the mouse, it is highlighted, click anywhere back in the RTB and the highlighting disappears. My programatically selected text remains selected.
I have some partially working code (below). I can clear all the highlighted text, but it is by process of selecting everything, changing the colour back and then deselecting it again. I know it is not efficient, the RTB flickers and I am sure it is not the correct way to do it. Can I emulate the standard windows behaviour?
Also using my code, it scrolls to the first line when entering the RTB a second time.
I get around this the first time by returning the top visible line index before clearing the text and then selecting that line again afterwards and using ScrollToCaret(). This only works on the first pass. Subsequent MouseDown events select the top row regardless of where the user has clicked so nothing can be manually highlighted in the RTB.
Private Sub rtbMain_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles rtbMain.MouseDown
Dim topIndex As Integer = rtbMain.GetCharIndexFromPosition(New System.Drawing.Point(1, 1))
Dim topLine As Integer = rtbMain.GetLineFromCharIndex(topIndex)
If e.Button = Windows.Forms.MouseButtons.Right Then
'Do nothing (Context Menu)
Else
rtbMain.SelectAll()
rtbMain.SelectionColor = Color.Black
rtbMain.SelectionBackColor = Color.White
rtbMain.DeselectAll()
rtbMain.Select(topIndex, 0)
rtbMain.ScrollToCaret()
End If
End Sub
I need my code to emulate the standard windows behaviour - clear selected text highlighting on MouseDown and leave the mouse cursor where the user has clicked.
Any help anyone can offer is gratefully appreciated.

I think you may be overthinking this one.
In the right click event, try RtbMain.SelectionLength = 0

Related

Odd behaviour when trying to de-selecting text in Combobox with SuggestAppend

I've got a DropDown combobox which is bound to a list. I am using SuggestAppend autocomplete based on the items from that list.
Once the item is selected from the suggest popup, the text is completed in the combobox as expected. However, the text stays selected and I am struggling to deselect it with an event. I can see a similar post (Deselect combobox text on leaving using suggestappend) , however the solution doesn't seem to apply in my case.
My combobox code:
Private Sub CboIFAfirm_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CboIFAfirm.SelectedIndexChanged
If CboIFAfirm.SelectedIndex > -1 Then
CboAdviser.SelectedIndex = -1
With CboIFAfirm
.SelectionStart = 0
.SelectionLength = 0
End With
CboAdviser.Select()
End If
End Sub
I have also tried setting the autocomplete mode to None before selecting the next Combobox without luck.
Interestingly, when text is selected the selectionlength shows 0 so it sorts of doesn't see it...
EDIT:
Another approach has failed too - I have added SendKeys.Send("{End}") at the bottom of my SelectedIndexChanged event but it only seems to work without selecting CboAdviser!?

Place a cursor (for editing) in datagridview cell text using a right click

Im trying to piece together vb.net code that will allow the user to right click in a datagridview and then place a cursor (or is it a caret?) into the text of the cell.
I can already get the row and cell using
Dim hti As DataGridView.HitTestInfo = sender.HitTest(e.X, e.Y)
and isolate the right click on a mouse down
If e.Button = Windows.Forms.MouseButtons.Right Then
I also have the position where the user right clicked using
Dim pt As Point = Me.PointToClient(Control.MousePosition)
what seams to elude me is how to put it all together to place the cursor where the user right clicked.
What I don't want is to place a cursor into a cell just anywhere, I need to place a cursor into the cells text (if any is there) where the user right clicked in the cell.
The point of the code will be to allow the user to place some text into the cell at the clicked position based on a selection from a right click menu. Appreciate any helpful suggestions.
Kind regards
Michael
Something like this possibly... should work reasonably well.
In your DataGridView CellMouseDown event handler:
If e.Button = MouseButtons.Right Then
'Get coordinates within cell
_point = New Point(e.X, e.Y)
'we are going to handle setting the edit state of the cell
_handleEdit = True
'Set current cell to the one we right clicked in (this will trigger the CellEnter event)
dataGridView1.CurrentCell = dataGridView1(e.ColumnIndex, e.RowIndex)
End If
In your DataGridView CellEnter event handler:
If _handleEdit Then
'enter edit state
dataGridView1.BeginEdit(False)
'set the seletionstart property based on position
CType(dataGridView1.EditingControl, TextBox).SelectionStart = CType(dataGridView1.EditingControl, TextBox).GetCharIndexFromPosition(_point)
'Done handling the edit state
_handleEdit = False
End If

Reversi VB.net logic behind it

I am trying to make the reversi game in VB.Net. I have some difficulties translating the game`s logic into vb.net
If a button is black and the button next to it is white,than the button next to the white one will be black wen pressed.
newButton.tag = colum of button + (row of button * amount of columns)
-> I made 64 buttons via a function loop and added a tag
Dim knop As Button = sender
Dim value As String = knop.Tag
If value = "...(?)" Then
knop.BackColor = Color.Black
If ....(?)
End If
End If
I already made a scheme with the label of the buttons, but I find it hard to implement the logic. Can someone help me out with thid one?
EDIT: http://i.stack.imgur.com/3gdrJ.png
If you use Dim ButtonList As List(Of List(Of Button)) and add the buttons to the form in runtime you can add each the button for each row to a list then add that list to ButtonList. Now you can access each button by the indexes in the 2 dimensional list.
Since you're changing the backcolor just use that instead of using the tag.

How to remove textboxes on button click (vb.net)?

I am not knowing about how to delete textboxes on the click of a button in my Windows form.
Here is my story:
Initially, I wanted to add textboxes on the click of a button, and upon searching the net, I was able to find out, on this forum, how to do this. https://stackoverflow.com/questions/15461978/adding-new-textbox-with-button-click
I used the code that user "Rajaprabhu Aravindasam" (2nd answer) gave. Here is only part of my code that I used (in order not to confuse you):
Private Sub Button_AddTask_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_AddTask.Click
count += 1
TabPage_TaskStructure.Controls.Add(New Label() With _
{.Name = "Label_Task" & count})
TabPage_TaskStructure.Controls.Add(New RichTextBox() With _
{.Name = "RichTextBox" & count})
End Sub
Now, as you can see, the purpose of the button 'Button_AddTask" ('+' button on my form) is to create rich textboxes and their respective label. Assume that the rich textboxes and the labels are being created below one another.
Beside the '+' button, there is a '-' button. What I want is to use this '-' button to delete all created textboxes sequentially up. That is, if I have created 4 textboxes with the button '+', textbox no.4 will be deleted first when I click the '-' button, then no. 3 after a second click, then no.2 after a third click and so on.
The sequential part is not a problem, I know perfectly how to do it. Here is part of the code I tried:
Private Sub Button_DeleteTask_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_DeleteTask.Click
TabPage_TaskStructure.Controls.Remove(New Label() With _
{.Name = "Label_Task" & count})
TabPage_TaskStructure.Controls.Remove(New RichTextBox() With _
{.Name = "RichTextBox" & count})
count -= 1
If count = 1 Then
Button_DeleteTask.Visible = False
End If
End Sub
What I did, logically, was simply replace 'Add' with 'Remove', but I am not knowing with what to replace 'New'. And so my question is: What needs to be used instead of 'New'? If I need to use an entirely different code, please do tell me.
Any help is greatly appreciated.
Update:
Ok, I have done some research since I've asked this question and I've been able to deduce that the removal of the controls (Label & Rich Text Box) can be done by using a For Each loop. In my code for the '-' button, I have replaced the first 4 lines of code with this:
Dim Ctrl As Control
For Each Ctrl In TabPage_TaskStructure.Controls
If TypeOf Ctrl Is Label And Ctrl.Name = "Label_Task" & count Then
TabPage_TaskStructure.Controls.Remove(Ctrl)
ElseIf TypeOf Ctrl Is RichTextBox And Ctrl.Name = "RichTextBox" & count Then
TabPage_TaskStructure.Controls.Remove(Ctrl)
End If
Next
And so, when I click the '-' button, the program checks whether each control on the tab page (TabPage_TaskStructure) is a label with the name ("Label_Task" & count') or a rich text box with the name ("RichTextBox" & count), and if they are, they will be removed. The rest of the code is the same.
It's working, however not completely. It's working for the labels as they are successfully being removed, but not for the rich text boxes. I cannot understand why. I have tried the code for other controls such as date time pickers and text boxes, and it's not working for any of these either. It seems to be working for labels only.
Also, I have tried using the code on a default rich text box, and it worked! But for rich text boxes being created at run time, it's not working.
Can anyone clarify me on this?
I'm not really good at vb but from simple logic if and when an "IF" argument is accepted the code will move to "End If" and skip "Else" altoghter.
Try this instead:
Dim Ctrl As Control
For Each Ctrl In TabPage_TaskStructure.Controls
If TypeOf Ctrl Is Label And Ctrl.Name = "Label_Task" & count Then
TabPage_TaskStructure.Controls.Remove(Ctrl)
End If
If TypeOf Ctrl Is RichTextBox And Ctrl.Name = "RichTextBox" & count Then
TabPage_TaskStructure.Controls.Remove(Ctrl)
End If
Next

VB.NET ComboBox - Need to force a redraw when a key is pressed when it is dropped down

I am using a DrawItem and MeasureItem events to paint a combobox with a DrawMode of OwnerDrawVariable.
Basically, I'm trying to have the user highlight a selection with the mouse, and then press the space bar to toggle the Save status of a song list. Then I call the Me.Refresh() event for the form in an attempt to redraw the form and the ComboBox.
The problem that I am running into is that only the Combobox itself (not the drop-down area) that is a control on the main form is redrawing, and the text that is behind the mouse-highlighted selection of the drop-down list is not changing from Red to Black as I believe it should. If I move the mouse to another selection, then the color does in fact update.
Here is a snippet of the code.
If (e.KeyCode = Keys.Space) Then
If cmbList.SelectedItem IsNot Nothing Then
With DirectCast(cmbList.SelectedItem, SongTitle)
.bSave = Not .bSave
End With
End If
End If
e.Handled = True
Me.Refresh()
Thanks for any help you can provide.
You need to use .RefreshItem/.RefreshItems instead of .Refresh.
See this question: Dynamically changing the text of items in a Winforms ComboBox