Как поместить мои сабы в фоновую работу

В моем приложении у меня есть 2 подпрограммы, которые, кажется, блокируют пользовательский интерфейс, RowPrePaint и CellFormatting. Эти 2 подпрограммы окрашивают мои ячейки DataGridView в определенные цвета в зависимости от того, какое значение находится внутри ячейки.

На основе другого вопроса Я спросил, я пришел к выводу, что мне нужна еще одна нить. (Ханс Пассант порекомендовал BackgroundWorker) Тогда я был еще новичком, поэтому я просто нашел обходные пути для своих проблем, и теперь они догнали меня, потому что такие инструменты, как DateTimePicker, не будут правильно работать в моем пользовательском интерфейсе.

Я искал примеры, и все они, похоже, включают фоновую работу, включающую индикатор выполнения или что-то подобное. Также я столкнулся с правилом, согласно которому никогда не обращайтесь к объектам пользовательского интерфейса в потоке, который их не создавал. Так что я запутался, стоит ли вообще ставить эти сабы на фоновую работу?

Итак, кто-нибудь знает какие-либо примеры, подобные этому, на которых я мог бы учиться? Или есть какие-нибудь советы о том, как я могу разместить эти сабвуферы в разных темах? Заранее спасибо. Я включил 2 сабвуфера Troublemaaker

    Private Sub DataGridView1_RowPrePaint(sender As Object, e As DataGridViewRowPrePaintEventArgs) Handles DataGridView1.RowPrePaint

    Dim Row As DataGridViewRow = DataGridView1.Rows(e.RowIndex)   

    If Row.Cells(3).Value = 7 Then
        Row.Cells(0).Style.BackColor = Color.LightSkyBlue
        Row.Cells(1).Style.BackColor = Color.LightSkyBlue
        Row.Cells(2).Style.BackColor = Color.LightSkyBlue
        Row.Cells(3).Style.BackColor = Color.LightSkyBlue
        Row.Cells(4).Style.BackColor = Color.LightSkyBlue
    ElseIf Row.Cells(3).Value = 8 Then
        Row.Cells(0).Style.ForeColor = Color.White
        Row.Cells(1).Style.ForeColor = Color.White
        Row.Cells(2).Style.ForeColor = Color.White
        Row.Cells(3).Style.ForeColor = Color.White
        Row.Cells(4).Style.ForeColor = Color.White
    End If

    Dim value As Integer = Convert.ToInt32(Row.Cells(5).Value)

    Select Case value
        Case "0"
            Row.Cells(5).Style.BackColor = Color.Empty
            Row.Cells(5).Style.ForeColor = Color.White
        Case "1"
            Row.Cells(0).Style.BackColor = Color.LightSkyBlue
            Row.Cells(1).Style.BackColor = Color.LightSkyBlue
            Row.Cells(2).Style.BackColor = Color.LightSkyBlue
            Row.Cells(4).Style.BackColor = Color.LightSkyBlue
            Row.Cells(5).Style.BackColor = Color.LightSkyBlue
            Row.Cells(5).Style.ForeColor = Color.LightSkyBlue
        Case "2"
            Row.Cells(0).Style.BackColor = Color.Chartreuse
            Row.Cells(1).Style.BackColor = Color.Chartreuse
            Row.Cells(2).Style.BackColor = Color.Chartreuse
            Row.Cells(4).Style.BackColor = Color.Chartreuse
            Row.Cells(5).Style.BackColor = Color.Chartreuse
            Row.Cells(5).Style.ForeColor = Color.Chartreuse
        Case "4"
            Row.Cells(0).Style.BackColor = Color.Gainsboro
            Row.Cells(1).Style.BackColor = Color.Gainsboro
            Row.Cells(2).Style.BackColor = Color.Gainsboro
            Row.Cells(4).Style.BackColor = Color.Gainsboro
            Row.Cells(5).Style.BackColor = Color.Gainsboro
            Row.Cells(5).Style.ForeColor = Color.Gainsboro
        Case "5"
            Row.Cells(0).Style.BackColor = Color.RoyalBlue
            Row.Cells(1).Style.BackColor = Color.RoyalBlue
            Row.Cells(2).Style.BackColor = Color.RoyalBlue
            Row.Cells(4).Style.BackColor = Color.RoyalBlue
            Row.Cells(5).Style.BackColor = Color.RoyalBlue
            Row.Cells(5).Style.ForeColor = Color.RoyalBlue
    End Select

    For colval As Integer = 7 To 51 Step 2

        Dim value6 As Integer = Row.Cells(colval).Value

        Select Case value6
            Case "0"
                Row.Cells(colval).Style.BackColor = Color.Empty
                Row.Cells(colval).Style.ForeColor = Color.White
            Case "1"
                Row.Cells(colval).Style.BackColor = Color.LightSkyBlue
                Row.Cells(colval).Style.ForeColor = Color.LightSkyBlue
            Case "2"
                Row.Cells(colval).Style.BackColor = Color.Chartreuse
                Row.Cells(colval).Style.ForeColor = Color.Chartreuse
            Case "3"
                Row.Cells(colval).Style.BackColor = Color.Orange
                Row.Cells(colval).Style.ForeColor = Color.Orange
            Case "4"
                Row.Cells(colval).Style.BackColor = Color.Gainsboro
                Row.Cells(colval).Style.ForeColor = Color.Gainsboro
            Case "5"
                Row.Cells(colval).Style.BackColor = Color.RoyalBlue
                Row.Cells(colval).Style.ForeColor = Color.RoyalBlue
            Case "6"
                Row.Cells(colval).Style.BackColor = Color.Red
                Row.Cells(colval).Style.ForeColor = Color.Red
        End Select

    Next colval

    Dim value53 As Integer = Row.Cells(53).Value

    Select Case value53
        Case "0"
            Row.Cells(53).Style.BackColor = Color.Empty
            Row.Cells(53).Style.ForeColor = Color.White
        Case "1"
            Row.Cells(53).Style.BackColor = Color.Chartreuse
            Row.Cells(53).Style.ForeColor = Color.Chartreuse
        Case "4"
            Row.Cells(53).Style.BackColor = Color.Gainsboro
            Row.Cells(53).Style.ForeColor = Color.Gainsboro
    End Select

End Sub

    Private Sub DataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting

    For k = 8 To 52 Step 2
        Dim row As DataGridViewRow = DataGridView1.Rows(e.RowIndex)                                                 'Declare part of the code to equal row (runs the code faster)
        If row.Cells(k).Value Is DBNull.Value Or row.Cells(k).Value Is Nothing Then Continue For                    'If the database has a null cell or the cell is nothing continue

        Dim firstDate As Date = DirectCast(row.Cells(k).Value, Date)                                                'Declare firstdate as a cell value and convert to date type
        Dim N As Date = Now                                                                                         'Declare N as the date today
        Dim diff As TimeSpan = N - firstDate                                                                        'Declare diff as the tome between N and firstdate

        If diff.Days > 14 AndAlso row.Cells(k + 1).Value = 0 Then                                                   'If the difference between 'diff' is over 14 and col in front of k equals 0
            row.Cells(k - 1).Value = 6                                                                              'Make col behind k = 6
        ElseIf diff.Days > 14 AndAlso row.Cells(k + 1).Value <> 0 Then                                              'Or if the difference between 'diff' is over 14 and col in front of k does not equal 0
            row.Cells(k - 1).Value = row.Cells(k - 3).Value                                                         'Make col behind k equal the value of the col 3 rows behind k
        End If
    Next k
End Sub

person Running Thru The 6With My Code    schedule 14.03.2017    source источник
comment
Эти подпрограммы событий автоматически вызываются datagridview, поэтому поместить их в фоновый рабочий процесс невозможно. Однако вы можете переместить код внутри рабочего, но вы не можете напрямую получить доступ к datagridview. Вместо этого вы должны вызвать сетку, чтобы прочитать ее свойства. CellFormatting запускается для каждой отображаемой новой ячейки. НЕ зацикливайтесь на нем. используйте e.ColumnIndex вместо k. Тем не менее, манипулирование значениями в событии форматирования тоже не лучший вариант.   -  person Keith Mifsud    schedule 14.03.2017
comment
В обоих ваших методах нет смысла выполнять их в фоновом режиме. В основном это операции пользовательского интерфейса, и нет длительной внешней операции.   -  person Sefe    schedule 14.03.2017
comment
Спасибо за ответ. @keith Я задал этот вопрос, потому что эти две конкретные подпрограммы мешают работе пользовательского интерфейса и блокируют появление окон сообщений впереди и т. д. Из вашего комментария вы бы сказали, что эти блоки кода должны быть в разных подпрограммах?   -  person Running Thru The 6With My Code    schedule 14.03.2017
comment
@Sefe, вот почему комментарий Ганса к моему другому вопросу меня немного сбил с толку. Эти 2 блока кода блокируют пользовательский интерфейс, и я изо всех сил пытаюсь понять, почему.   -  person Running Thru The 6With My Code    schedule 14.03.2017
comment
Сами сабы не проблема - код в них неправильный. Кроме того, включите Option Strict — целое число никогда не может быть равно 3 или 5.   -  person Ňɏssa Pøngjǣrdenlarp    schedule 14.03.2017
comment
@Plutonix спасибо за ответ. У меня уже есть строгая опция, и никаких ошибок не появляется. так что, если я исправлю код, убрав цикл из форматирования ячейки и т. д., тогда он должен работать?   -  person Running Thru The 6With My Code    schedule 14.03.2017
comment
Извините, но Select Case value ... Case "0", когда значение является целым числом, не будет компилироваться под Option Strict - вы сравниваете целое число со строковым литералом. Это применимо в нескольких отношениях   -  person Ňɏssa Pøngjǣrdenlarp    schedule 14.03.2017
comment
Привет @KeithMifsud. Я хочу заменить циклы в своих сабвуферах, так как думаю, что это решит мою проблему, но мне нужен блок кода, чтобы воздействовать на каждый второй столбец в DataGridView. Как я мог изменить k на e.ColumnIndex и при этом работать только с каждыми двумя столбцами?   -  person Running Thru The 6With My Code    schedule 20.03.2017
comment
вы можете использовать оператор Mod. If e.ColumnIndex >= 8 AndAlso e.ColumnIndex <= 52 AndAlso e.ColumnIndex Mod 2 = 0 Then Это устранит цикл for и заменит все k на e.ColumnIndex   -  person Keith Mifsud    schedule 20.03.2017