DataGridView + TextBox How to colorate more and different values - vb.net

I have a problem, with DataGridView's CellFormatting. The cells are colored by the search result from a TextBox. When I search for 2 numbers together, they are no longer colored. What should I do?
I state that I am using CONCAT_WS to load the table in DataGridView. What can I do?
Private Sub DataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
Try
If e.ColumnIndex = 3 And e.Value IsNot Nothing Or e.ColumnIndex = 4 And e.Value IsNot Nothing Or e.ColumnIndex = 5 And e.Value IsNot Nothing Or e.ColumnIndex = 6 And e.Value IsNot Nothing Or e.ColumnIndex = 7 And e.Value IsNot Nothing Then
If String.IsNullOrEmpty(txtRefreshFiltra.Text) Then
txtRefreshFiltra.Text = ""
End If
Dim sum6 As String = Convert.ToInt32(e.Value)
If sum6 = txtRefreshFiltra.Text Then
e.CellStyle.BackColor = Color.Gold
e.CellStyle.ForeColor = Color.Black
End If
End If
Catch ex As Exception
MsgBox(ex.Message) 'show error msg'
End Try
End Sub
My connection
Public Sub FilterData(ValueToSearch As String)
Try
Dim SearchQyery As String = "SELECT * FROM LottoDeaBendata WHERE CONCAT_WS([Estratto1],[Estratto2],[Estratto3],[Estratto4],[Estratto5])LIKE'%" & ValueToSearch & "%'"
Dim command As New SqlCommand(SearchQyery, connection)
connection.Open()
Dim table As New DataTable()
Dim adapter As New SqlDataAdapter(command)
adapter.Fill(table)
DataGridView1.DataSource = table
connection.Close()
Catch ex As Exception
MsgBox(ex.Message) 'show error msg'
End Try
End Sub
Upload by button
Private Sub btnFiltraDati_Click(sender As Object, e As EventArgs) Handles btnFiltraDati.Click
FilterData(txtRefreshFiltra.Text)
End Sub

There are a few things you may want to consider to color the cells as you describe. First, using the grids CellFormatting event may not necessarily be the best choice. This event will fire once for each cell when the data is loaded into the grid and this is fine and colors the cells as we want when the data is loaded, however, it also may fire if the user simply moves the cursor over a cell or the user scrolls the grid.
In both the cases of the user moving the cursor over a cell or scrolling the grid, clearly demonstrates that the cells will get re-colored unnecessarily. In other words, if the text in the text box has not changed or a cells value has not changed, then, re-coloring the cell(s) is superfluous.
Given this, the only drawback to NOT using the grids CellFormatting event is that our code will have to color the cells AFTER the grid is loaded with data. This means we will need a method to loop through all the rows of the grid to check and color the cells. This method to color all the cells is also going to be needed if the text in the text box changes. So, making this method makes sense so we can call it when the data is loaded and also when the text box text changes.
So given all this, to simplify things, I suggest you create a method that takes a single DataGridViewCell. The method will get the comma separated values from the text box and compare the cells value to the values in the text box and if one matches, then we simply color the cell, otherwise do not color the cell.
This method is below. First, we check if the cell is not null and actually has some value. Then, we take the string in the text box and split it on commas. Then we start a loop through all the values in the split string from the text box and if a match is found, then we simply color the cell and exit the for each loop.
Private Sub ColorCell(cell As DataGridViewCell)
If (cell.Value IsNot Nothing) Then
Dim target = cell.Value.ToString()
If (Not String.IsNullOrEmpty(target)) Then
cell.Style.BackColor = Color.White
cell.Style.ForeColor = Color.Black
Dim split = txtRefreshFiltra.Text.Trim().Split(",")
For Each s As String In split
If (target = s.Trim()) Then
cell.Style.BackColor = Color.Gold
cell.Style.ForeColor = Color.Black
Exit For
End If
Next
End If
End If
End Sub
The method above should simplify looping through all the rows in the grid to color the proper cells. This method may look something like below and we would call this method once after the data is loaded into the grid and also when the text in the text box changes.
Private Sub ColorAllCells()
For Each row As DataGridViewRow In DataGridView1.Rows
ColorCell(row.Cells(3))
ColorCell(row.Cells(4))
ColorCell(row.Cells(5))
ColorCell(row.Cells(6))
ColorCell(row.Cells(7))
Next
End Sub
Lastly, the two event methods that we need to capture when the user changes a cells value in the grid in addition to when the user changes the text in the text box.
Private Sub txtRefreshFiltra_TextChanged(sender As Object, e As EventArgs) Handles txtRefreshFiltra.TextChanged
ColorAllCells()
End Sub
Private Sub DataGridView1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
If (e.RowIndex >= 0) Then
If (e.ColumnIndex = 3 Or e.ColumnIndex = 4 Or e.ColumnIndex = 5 Or e.ColumnIndex = 6 Or e.ColumnIndex = 7) Then
ColorCell(DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex))
End If
End If
End Sub
Edit per OP comment…
There are definitely a couple of things we can do to speed up the current code above, like take out the call to ColorAllCells in the text boxes TextChanged event.
The TextChanged event will fire when the user types a single character. Example, if the user wants to color the cells that are “55”, then, when the user types the first “5” into the text box… then the TextChanged event will fire and the code will color all the cells with “5”. Then when the user types the second “5”, the cells will be un-colored/colored again.
So, one way we can prevent the unnecessary coloring as described above is to NOT call the ColorAllCells method in the text boxes TextChanged event and simply put the ColorAllCells method into a button click. In other words, the user types what they want into the text box… THEN clicks a button to color the cells.
In addition, if you look at the ColorCell method, you may note that each time the method is called, the code is splitting the same string over and over with … Dim split = txtRefreshFiltra.Text.Trim().Split(",") … this is potentially redundant in a sense that the text … txtRefreshFiltra.Text may not have changed.
Therefore, to remedy this and only split the txtRefreshFiltra.Text when needed, we will use a global variable called something like currentSplit that holds the current split of the text box. Then we would “update” the currentSplit variable only when needed… like in its TextChanged event.
This should somewhat speed things up. In my small tests, it took approximately 10 seconds to color the cells the FIRST time. Subsequent coloring of the cells when the text box value was changed took less than 1 second.
First make a global variable to hold the current text boxes split values…
Dim currentSplit As String()
Then change the other methods as shown below…
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dt = GetDT()
DataGridView1.DataSource = dt
currentSplit = txtRefreshFiltra.Text.Trim().Split(",")
End Sub
Private Sub ColorCell(cell As DataGridViewCell)
If (cell.Value IsNot Nothing) Then
Dim target = cell.Value.ToString()
If (Not String.IsNullOrEmpty(target)) Then
cell.Style.BackColor = Color.White
cell.Style.ForeColor = Color.Black
For Each s As String In currentSplit
If (target = s.Trim()) Then
cell.Style.BackColor = Color.Gold
cell.Style.ForeColor = Color.Black
Exit For
End If
Next
End If
End If
End Sub
Private Sub txtRefreshFiltra_TextChanged(sender As Object, e As EventArgs) Handles txtRefreshFiltra.TextChanged
currentSplit = txtRefreshFiltra.Text.Trim().Split(",")
End Sub
And finally, a button click event to color the cells. I added a stop watch to time how long it takes to color the cells.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sw As Stopwatch = New Stopwatch()
Debug.WriteLine("Starting coloring of cells -------")
sw.Start()
ColorAllCells()
sw.Stop()
Debug.WriteLine("It took: " + sw.Elapsed.TotalSeconds.ToString() + " to color the cells of 100,000 rows with 10 columns")
End Sub

Related

Implementing a Text change event from an Array

I am looking to change textbox fore and back colors of multiple textboxes based on a value if any one of the textboxes change it's value either by user input or reading from the DB.
I am not sure how to implement the code once an individual textbox has a change. The below code is as far as I got as I do not know how to implement it to work. Can someone assist?
Private Sub DiffCalcColor_TextChanged(sender As Object, e As EventArgs) Handles tbPMDiffCalc.TextChanged, tbLHDiffCalc.TextChanged, tbRFDiffCalc.TextChanged, tbFSDiffCalc.TextChanged, tbFSADiffCalc.TextChanged
Dim tb = DirectCast(sender, TextBox)
Dim text = tb.Text.Replace("$", "")
Dim number As Decimal
Decimal.TryParse(text, number)
Select Case number
Case < 0D : tb.ForeColor = Color.DarkRed
tb.BackColor = Color.White
Case > 0D : tb.ForeColor = Color.Green
tb.BackColor = Color.White
Case = 0D : tb.ForeColor = Color.DimGray
tb.BackColor = Color.Gainsboro
Case Else
Exit Select
End Select
End Sub
If you want to handle the same event for multiple controls with a single method then you simply include all those controls in the Handles clause, e.g.
Private Sub TextBoxes_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged,
TextBox2.TextChanged
Dim eventRaiser = DirectCast(sender, TextBox)
'Get the text that just changed.
Dim text = eventRaiser.Text
Dim number As Decimal
'Try to convert it to a number.
Decimal.TryParse(text, number)
'Use the number to decide how to format.
If number = Decimal.Zero Then
'...
Else
'...
End If
End Sub
You can do that manually or you can let the designer do it for you. To do the latter, start by selecting the multiple controls in the designer, then open the Properties window, click the Events button on the toolbar, then double-click the appropriate event. That will generate an event handler, much like double-clicking on a single control does, but it will add all the selected controls to the Handles clause. It also allows you to generate a handler for any event, rather than just the default event. To add a control to that Handles clause, you can select one or more controls, select the event and then select an existing event handler from the drop-down.

DataGridView loses cell formatting from DataTable.AcceptChanges

VB2010. I have researched this issue and cannot seem to find a reason for it or a workaround. What I have is a DataGridView that is bound to a DataTable. I allow the user to select Edit mode which turns ON/OFF the ReadOnly property. Once ReadMode=True I make sure to set the DataTable to AcceptChanges. When this property is set all my cell formatting disappears.
I do this on form load:
Private Sub frmMain_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
dgv.DataSource = Nothing
dgv.DataSource = GetTripData()
dgv.AutoResizeColumns()
dgv.ClearSelection()
dgv.ReadOnly = True
End Sub
Then the user can click on a menu item to go into Edit Mode:
Private Sub mnuEditMode_Click(sender As System.Object, e As System.EventArgs) Handles mnuEditMode.Click
If mnuEditMode.Checked Then
dgv.ReadOnly = False
dgv.AllowUserToAddRows = True
dgv.AllowUserToDeleteRows = True
Else
dgv.ReadOnly = True
dgv.AllowUserToAddRows = False
dgv.AllowUserToDeleteRows = False
'accept all changes. if we dont do this any row that is deleted will still exist in the DataTable.
Dim dt As DataTable = CType(dgv.DataSource, DataTable)
If dt IsNot Nothing Then
dt.AcceptChanges() 'note: this causes custom cell font to be cleared
End If
End If
End Sub
Once in edit mode they can dictate which cells to change. Two cells they put in the list to change are treated a such:
'update the proper cells via the DataGridView
dgv.Rows(2).Cells(5).Value = "HOME"
dgv.Rows(2).Cells(6).Value = 10
'bold the cell's font in the DataGridView
Dim styleUpdated As New DataGridViewCellStyle
styleUpdated.Font = New Font(dgv.Font, FontStyle.Bold)
dgv.Rows(2).Cells(6).Style = styleUpdated
dgv.Rows(2).Cells(6).Style = styleUpdated
'refresh the DGV
dgv.Refresh()
This works! I can see the changes in the DGV. Now they are done with editing the data so they click on the menu item to set Edit Mode Off and that sets dgv.ReadOnly=True and I also set dt.AcceptChanges. This last method AcceptChanges clears all the bold fonts on modified cells.
Is this expected behavior? If so what suggestions are there to keep my edited cell formatting?
This isn't really an answer but I want to post a significant piece of code so I'm posting it as an answer. I just tested the following code and it worked for me, in that the bold text remained as the two Buttons were clicked.
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim table As New DataTable
With table.Columns
.Add("Id", GetType(Integer))
.Add("Name", GetType(String))
.Add("Age", GetType(Integer))
End With
With table.Rows
.Add(1, "Mary", 20)
.Add(2, "Paul", 30)
.Add(3, "Peter", 40)
End With
DataGridView1.DataSource = table
Dim style = DataGridView1.Rows(1).Cells(1).Style
style.Font = New Font(DataGridView1.Font, FontStyle.Bold)
DataGridView1.Rows(1).Cells(1).Style = style
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
With DataGridView1
.ReadOnly = True
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
End With
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
With DataGridView1
.ReadOnly = False
.AllowUserToAddRows = True
.AllowUserToDeleteRows = True
End With
End Sub
End Class
I'd suggest that you give that code a go and, if it works for you, you know that there's something else going on in your original project. You can then modify that test project slowly to make it more and more like your existing project and you should then be able to see where this functionality breaks.
I looked some more and I think the cell formatting clearing is expected behavior. So I came up with a small routine that will save each cell's formatting and then re-apply it after the AcceptChanges. Note that my DataTable is small so you may get a performance hit if you have a large dataset. Please provide any feedback if I have missed something:
'updated routine to implement AcceptChanges
'dt.AcceptChanges() 'note: this causes custom cell font to be cleared
DgvAcceptChanges(dgvMain)
''' <summary>
''' this routine will take a DataGridView and save the style for each cell, then it will take it's DataTable source and accept any
''' changes, then it will re-apply the style font to each DataGridView cell. this is required since DataTable.AcceptChanges will
''' clear any DataGridView cell formatting.
''' </summary>
''' <param name="dgv">DataGridView object</param>
''' <remarks>Could be extended to do other things like cell ReadOnly status or cell BackColor.</remarks>
Public Sub DgvAcceptChanges(dgv As DataGridView)
Dim dt As DataTable = CType(dgv.DataSource, DataTable)
If dt IsNot Nothing Then
'save the DataGridView's cell style font to an array
Dim cellStyle(dgv.Rows.Count - 1, dgv.Columns.Count - 1) As DataGridViewCellStyle
For r As Integer = 0 To dgv.Rows.Count - 1
'the DataGridViewRow.IsNewRow Property = Gets a value indicating whether the row is the row for new records.
'Remarks: Because the row for new records is in the Rows collection, use the IsNewRow property to determine whether a row
'is the row for new records or is a populated row. A row stops being the new row when data entry into the row begins.
If Not dgv.Rows(r).IsNewRow Then
For c As Integer = 0 To dgv.Columns.Count - 1
cellStyle(r, c) = dgv.Rows(r).Cells(c).Style
Next c
End If
Next r
'this causes custom cell font to be cleared in the DataGridView
dt.AcceptChanges()
're-apply the DataGridView's cell style font from an array
For r As Integer = 0 To dgv.Rows.Count - 1
If Not dgv.Rows(r).IsNewRow Then
For c As Integer = 0 To dgv.Columns.Count - 1
dgv.Rows(r).Cells(c).Style.Font = cellStyle(r, c).Font
Next c
End If
Next r
End If
End Sub

vb.net datagrid to datagridview winforms

We work with vb.net - Visual Studio 2013 (WinForms)
We are changing datagrids to datagridviews in our code.
At the moment I'm trying to convert a column that was described in the datagrid as follows:
Dim grdcolstyle5 As New PTSoft.FrameWork.DataBrowserTextColumnColorDecimal
With grdcolstyle5
.HeaderText = "text"
.MappingName = "vrd_199"
.Width = 80
.FormatString = "###,###,##0.00"
.[Operator] = "<"
.ParameterCol = 2
.ForeBrush = New SolidBrush(Color.Red)
End With
What is does is compare the value of one column with another and color the text when it's smaller (in this case).
I know how to do it in a loop after the grid has been filled, but this slows things somewhat down.
Does anyone know how this can be done "on the fly", on the moment the row is filled?
In short I am looking for the equivalent for the datagridview...
You can use RowPrePaint event, where you have large number of rows to paint.
Private Sub dataGridView1_RowPrePaint(ByVal sender As Object, ByVal e As DataGridViewRowPrePaintEventArgs)
If Convert.ToInt32(dataGridView1.Rows(e.RowIndex).Cells(2).Text) < Convert.ToInt32(dataGridView1.Rows(e.RowIndex).Cells(5).Text) Then
dataGridView1.Rows(e.RowIndex).DefaultCellStyle.ForeColor = Color.Red
End If
End Sub
The above code is comparing Cells(2) against Cells(5). You can customize that as per your need.
Another option is using CellFormattingEvent
Private Sub dataGridView1_CellFormatting(ByVal sender As Object, ByVal e As DataGridViewCellFormattingEventArgs)
For Each Myrow As DataGridViewRow In dataGridView1.Rows
If Convert.ToInt32(Myrow.Cells(2).Value) < Convert.ToInt32(Myrow.Cells(1).Value) Then
Myrow.DefaultCellStyle.ForeColor = Color.Red
End If
Next
End Sub

programmatically select and highlight a row of a ListView in VB.NET

I want to do something seemingly simple - programmatically select and highlight a row of a ListView in VB.NET.
VB.NET: How to dynamically select a list view item?
tells me what should to be all that is needed, but it isn't. The row is selected, but not highlighted.
http://vbcity.com/forums/t/28260.aspx
tells me about the "HideSelection" property and the .Focus() method (also referenced at Select programmatically a row of a Listview), which sounded hopeful, but the best I can get is the faint highlight mentioned, I want the full monty. I tried a Noddy example with just a ListView, in Details mode, FullRowSelection = true, HideSelection = False, one columnheader defined and then
ListView1.Items.Add("Red")
ListView1.Items.Add("Orange")
ListView1.Items.Add("Yellow")
ListView1.Items.Add("Green")
ListView1.Items(2).Selected = True
I get this
but I want this
I can simulate highlighting by adding these lines
ListView1.SelectedItems(0).BackColor = Color.CornflowerBlue
ListView1.SelectedItems(0).ForeColor = Color.White
but then how can I be sure to undo the artificial highlight if the row can be implicitly as well as explicitly deselected? Do I have to think of all the possible cases? That's too much work for what should be a simple operation. Plus, since I want to color-code my rows, there is an additional challenge that when I undo the highlight color, I have to figure out what color is appropriate at that point. Is there a better, simpler way?
You can access the Graphics object used to draw each item, and draw them yourself.
Make a new project with a Button and ListView. Paste the following code:
Form_Load to use multiple subitems
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.ListView1.OwnerDraw = True ' or else can't handle DrawItem event
ListView1.Columns.Add("ColumnHeader1")
ListView1.Columns.Add("ColumnHeader2")
ListView1.Columns.Add("ColumnHeader3")
Me.ListView1.Items.Add("Red")
Me.ListView1.Items.Add("Orange")
Me.ListView1.Items.Add("Yellow")
Me.ListView1.Items.Add("Green")
ListView1.Items(0).SubItems.Add("Strawberry")
ListView1.Items(0).SubItems.Add("Apple")
ListView1.Items(1).SubItems.Add("Pepper")
ListView1.Items(1).SubItems.Add("Apricot")
ListView1.Items(2).SubItems.Add("Plum")
ListView1.Items(2).SubItems.Add("Banana")
ListView1.Items(3).SubItems.Add("Apple")
ListView1.Items(3).SubItems.Add("Lime")
End Sub
Three handlers for the ListView's drawing related events. Code copied from this answer
Private Sub listView1_DrawColumnHeader(sender As Object, e As DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
e.DrawDefault = True
End Sub
Private Sub listView1_DrawSubItem(sender As Object, e As DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
Const TEXT_OFFSET As Integer = 1
' I don't know why the text is located at 1px to the right. Maybe it's only for me.
Dim listView As ListView = DirectCast(sender, ListView)
' Check if e.Item is selected and the ListView has a focus.
If Not listView.Focused AndAlso e.Item.Selected Then
Dim rowBounds As Rectangle = e.SubItem.Bounds
Dim labelBounds As Rectangle = e.Item.GetBounds(ItemBoundsPortion.Label)
Dim leftMargin As Integer = labelBounds.Left - TEXT_OFFSET
Dim bounds As New Rectangle(rowBounds.Left + leftMargin, rowBounds.Top, If(e.ColumnIndex = 0, labelBounds.Width, (rowBounds.Width - leftMargin - TEXT_OFFSET)), rowBounds.Height)
Dim align As TextFormatFlags
Select Case listView.Columns(e.ColumnIndex).TextAlign
Case HorizontalAlignment.Right
align = TextFormatFlags.Right
Exit Select
Case HorizontalAlignment.Center
align = TextFormatFlags.HorizontalCenter
Exit Select
Case Else
align = TextFormatFlags.Left
Exit Select
End Select
TextRenderer.DrawText(e.Graphics, e.SubItem.Text, listView.Font, bounds, SystemColors.HighlightText, align Or TextFormatFlags.SingleLine Or TextFormatFlags.GlyphOverhangPadding Or TextFormatFlags.VerticalCenter Or TextFormatFlags.WordEllipsis)
Else
e.DrawDefault = True
End If
End Sub
Private Sub listView1_DrawItem(sender As Object, e As DrawListViewItemEventArgs) Handles ListView1.DrawItem
Dim listView As ListView = DirectCast(sender, ListView)
' Check if e.Item is selected and the ListView has a focus.
If Not listView.Focused AndAlso e.Item.Selected Then
Dim rowBounds As Rectangle = e.Bounds
Dim leftMargin As Integer = e.Item.GetBounds(ItemBoundsPortion.Label).Left
Dim bounds As New Rectangle(leftMargin, rowBounds.Top, rowBounds.Width - leftMargin, rowBounds.Height)
e.Graphics.FillRectangle(SystemBrushes.Highlight, bounds)
Else
e.DrawDefault = True
End If
End Sub
Button click handler to simulate item(2) selected
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.ListView1.Items(2).Selected = True
End Sub
This will draw the background color regardless of focus. You have a lot of control over other colors and fonts going this route too.
Here, the button has been clicked, to select item 2, while the button still has focus, and item 2 is selected.
Easiest thing,
Just allocate the LST_ItemIndex = lstList.FocusedItem.Index everytime you select a different item
and then fire the below whenever you want the highlight
If lstList.Items.Count > 0 Then
lstList.Items(LST_ItemIndex).Selected = True
lstList.Items(LST_ItemIndex).EnsureVisible()
End If

Capture CTRL+V or paste in a textbox in .NET

VB.NET 2010 - I have a RichTextbox in which the user can manually enter data or copy/paste from another source. After the data is complete he hits go and a few key words are highlighted. My issue is that if he copy/pastes from another source the formatting also gets copied. Well sometimes the outside source has a white font and my textbox has a white background so it appears like he pasted nothing and he does it again and again.
What I'm looking for is a way to intercept the paste action into the textbox so that I can take that text and paste it as pure ASCII without formatting.
Edit after experimenting with KeyDown
Private Sub txtRch_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles txtRch.KeyDown
If e.Modifiers = Keys.Control AndAlso e.KeyCode = Keys.V Then
With txtRch
Dim i As Integer = .SelectionStart 'cache the current position
.Select(0, i) 'select text from start to current position
Dim s As String = .SelectedText 'copy that text to a variable
.Select(i, .TextLength) 'now select text from current position to end
Dim t As String = .SelectedText 'copy that text to a variable
Dim u As String = s & Clipboard.GetText(TextDataFormat.UnicodeText) & t 'now concatenate the first chunk, the new text, and the last chunk
.Clear() 'clear the textbox
.Text = u 'paste the new text back into textbox
.SelectionStart = i 'put cursor back to cached position
End With
'the event has been handled manually
e.Handled = True
End If
End Sub
This seems to work and all my text gets retained and its all ASCII. I think if I wanted to take a step further I could also take the font and forecolor of my RichTextbox, select all text, and then assign the font and forecolor to the selection.
In most cases, examining the KeyDown event should be good enough along with using a temporary RichTextBox to modify the incoming text:
Private Sub RichTextBox1_KeyDown(sender As Object, e As KeyEventArgs) _
Handles RichTextBox1.KeyDown
If e.Modifiers = Keys.Control AndAlso e.KeyCode = Keys.V Then
Using box As New RichTextBox
box.SelectAll()
box.SelectedRtf = Clipboard.GetText(TextDataFormat.Rtf)
box.SelectAll()
box.SelectionBackColor = Color.White
box.SelectionColor = Color.Black
RichTextBox1.SelectedRtf = box.SelectedRtf
End Using
e.Handled = True
End If
End Sub
Note: Missing any error checking.