Представление ColumnIndex и DisplayIndex Datagrid

Эй, я пытаюсь изменить индекс столбца моего dvg, когда я меняю Displayindex, используя свойство Allowusertoordercolumns, но когда я перемещаю столбцы, я не могу заставить его изменить индекс столбца.

Я получаю сообщение об ошибке, в котором говорится, что индекс столбца доступен только для чтения. Вот что у меня есть до сих пор

Private Sub DataGridView1_ColumnDisplayIndexChanged(sender As Object, e As DataGridViewColumnEventArgs) _
 Handles DataGridView1.ColumnDisplayIndexChanged

    Dim messageBoxVB As New System.Text.StringBuilder()
    messageBoxVB.AppendFormat("{0} = {1}", "Column", e.Column)
    messageBoxVB.AppendLine()
    '   MessageBox.Show(messageBoxVB.ToString(), "ColumnDisplayIndexChanged Event")

    If DataGridView1.Columns(e.Column.Name).Index <> e.Column.DisplayIndex Then
        DataGridView1.Columns(e.Column.Name).Index = (e.Column.DisplayIndex)
    End If
    'DataGridView1 = DataGridView1
End Sub

КНОПКА

Это то, что я получил с помощью кнопки сопоставления, ничего из того, что я хочу сейчас

    Dim nbColumnsToTransfer As Integer = DataGridView2.Columns.GetColumnCount(1)

    Dim indexes As List(Of Integer) = (From column As DataGridViewColumn In DataGridView1.Columns.Cast(Of DataGridViewColumn)() _
                                          Take nbColumnsToTransfer _
                                          Order By column.DisplayIndex _
                                          Select column.Index).ToList()


    For c As Integer = 0 To DataGridView1.Rows.Count - 2

        Dim RNUM1 = (DataGridView1.Rows(c).Cells(indexes(0)).Value)
        Dim RNUM2 = (DataGridView1.Rows(c).Cells(indexes(1)).Value)
        If chkContactSplitReq.Checked = True Then

            If IsDBNull(DataGridView1.Rows(c).Cells(indexes(2)).Value) Then


                Dim RNUM3 As String = ""
                Dim RNUM4 As String = ""
                Dim RNUM5 = (DataGridView1.Rows(c).Cells(indexes(5)).Value)
                Dim RNUM6 = (DataGridView1.Rows(c).Cells(indexes(6)).Value)
                Dim RNUM7 = (DataGridView1.Rows(c).Cells(indexes(7)).Value)

                DataGridView2.Rows.Add(RNUM1, RNUM2, RNUM3, RNUM4, RNUM5, RNUM6, RNUM7)

            Else

                Dim tempString As String = (DataGridView1.Rows(c).Cells(indexes(2)).Value)
                Dim Split() As String = tempString.Split(" "c)
                Dim RNUM3 As String = Split(0)
                If Split.Length > 1 Then
                    Dim RNUM4 As String = Split(1)
                    Dim RNUM5 = (DataGridView1.Rows(c).Cells(indexes(4)).Value)
                    Dim RNUM6 = (DataGridView1.Rows(c).Cells(indexes(5)).Value)
                    Dim RNUM7 = (DataGridView1.Rows(c).Cells(indexes(6)).Value)

                    DataGridView2.Rows.Add(RNUM1, RNUM2, RNUM3, RNUM4, RNUM5, RNUM6, RNUM7)
                Else
                    Dim RNUM4 As String = ""
                    Dim RNUM5 = (DataGridView1.Rows(c).Cells(indexes(4)).Value)
                    Dim RNUM6 = (DataGridView1.Rows(c).Cells(indexes(5)).Value)
                    Dim RNUM7 = (DataGridView1.Rows(c).Cells(indexes(6)).Value)

                    DataGridView2.Rows.Add(RNUM1, RNUM2, RNUM3, RNUM4, RNUM5, RNUM6, RNUM7)
                End If
            End If
        Else
            Dim RNUM3 = (DataGridView1.Rows(c).Cells(indexes(2)).Value)
            Dim RNUM4 = (DataGridView1.Rows(c).Cells(indexes(3)).Value)
            Dim RNUM5 = (DataGridView1.Rows(c).Cells(indexes(4)).Value)
            Dim RNUM6 = (DataGridView1.Rows(c).Cells(indexes(5)).Value)
            Dim RNUM7 = (DataGridView1.Rows(c).Cells(indexes(6)).Value)

            DataGridView2.Rows.Add(RNUM1, RNUM2, RNUM3, RNUM4, RNUM5, RNUM6, RNUM7)
        End If

person Richard    schedule 25.03.2015    source источник
comment
Нет, вы не можете изменить индекс столбца DataGridView. Почему вы хотите это сделать?   -  person actaram    schedule 25.03.2015
comment
Здесь можно найти и интересное замечание: Значение этого свойства не обязательно соответствует текущему визуальному положению бэнда в коллекции. Например, если пользователь меняет порядок столбцов в DataGridView во время выполнения (при условии, что для свойства AllowUserToOrderColumns задано значение true), значение свойства Index каждого столбца не изменится. Вместо этого значения столбца DisplayIndex изменяются. Однако сортировка строк изменяет их значения индекса.   -  person actaram    schedule 25.03.2015
comment
Видите, я пытаюсь сопоставить два разных dgv, загружаю данные из листа excel spreed в один, затем меняю положение столбцов, чтобы они соответствовали положению второго представления данных, а затем передаю данные. Поскольку вновь добавленная таблица будет каждый раз отличаться, и, возможно, будут разные заголовки, например, Company и CompanyName, я не был уверен, как это сделать.   -  person Richard    schedule 25.03.2015
comment
Я не уверен, что понимаю. Является ли ваш второй DataGridView клоном первого?   -  person actaram    schedule 25.03.2015
comment
это клон некоторых колонок. Некоторых из первых дгв заводить не надо кидал.   -  person Richard    schedule 25.03.2015


Ответы (1)


Если бы я хорошо понял, что вы хотите сделать, вы могли бы сделать это так, чтобы загрузить данные из вашего первого DataGridView во второй:

DataGridView2.Rows.Clear()
For i As Integer = 0 to DataGridView1.Rows.Count - 1
    Datagridview2.Rows.Add(Datagridview1.Rows(i).Cells("FirstColumn").Value, Datagridview1.Rows(i).Cells("SecondColumn").Value, Datagridview1.Rows(i).Cells("ThirdColumn").Value)
    ' or
    ' Datagridview2.Rows.Add(Datagridview1.Rows(i).Cells(0).Value, Datagridview1.Rows(i).Cells(1).Value, Datagridview1.Rows(i).Cells(2).Value)
Next

Таким образом, вам не нужно переупорядочивать столбцы второго DataGridView, если вы этого не хотите. В любом случае, одно можно сказать наверняка: свойство index DataGridViewColumn доступно только для чтения, поэтому вы не можете сделать это так, как хотели.

Изменить

Если вы не против использовать немного Linq, вы можете сделать что-то вроде этого. Вы также можете сделать это без Linq, но вот идея:

Dim NbOfSecondGridviewColumns As Integer = 3    
Dim indexes As List(Of Integer) = (From column As DataGridViewColumn In DataGridView1.Columns.Cast(Of DataGridViewColumn)() _
                                   Take NbOfSecondGridviewColumns _
                                   Order By column.DisplayIndex _
                                   Select column.Index).ToList()

For i As Integer = 0 to DataGridView1.Rows.Count - 1
    Datagridview2.Rows.Add(Datagridview1.Rows(i).Cells(indexes(0)).Value, Datagridview1.Rows(i).Cells(indexes(1)).Value, Datagridview1.Rows(i).Cells(indexes(2)).Value)
Next

Изменить 2

Вот что я бы сделал в вашем коде кнопки:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim nbColumnsToTransfer As Integer = DataGridView2.Columns.GetColumnCount(1)

    ' Get the indexes of the first [nbColumnsToTransfer] columns, ordered by their 
    ' display index, because your columns to be transferred are the first displayed
    Dim indexes As List(Of Integer) = (From column As DataGridViewColumn In DataGridView1.Columns.Cast(Of DataGridViewColumn)() _
                                       Take nbColumnsToTransfer _
                                       Order By column.DisplayIndex _
                                       Select column.Index).ToList()

    For c As Integer = 0 To DataGridView1.Rows.Count - 1

        ' Dim RNUM1 = (DataGridView1.Rows(c).Cells(0).Value) => this won't work 
        ' because cells takes a column index value or column name in parameter. Don't 
        ' forget your columns displayed index ≠ your columns index,
        ' that's why I used the linq query above
        Dim RNUM1 = (DataGridView1.Rows(c).Cells(indexes(0)).Value)
        Dim RNUM2 = (DataGridView1.Rows(c).Cells(indexes(1)).Value)
        Dim RNUM3 = (DataGridView1.Rows(c).Cells(indexes(2)).Value)
        Dim RNUM4 = (DataGridView1.Rows(c).Cells(indexes(3)).Value)
        Dim RNUM5 = (DataGridView1.Rows(c).Cells(indexes(4)).Value)
        Dim RNUM6 = (DataGridView1.Rows(c).Cells(indexes(5)).Value)
        Dim RNUM7 = (DataGridView1.Rows(c).Cells(indexes(6)).Value)

        DataGridView2.Rows.Add(RNUM2, RNUM4, RNUM3, RNUM3, RNUM6, RNUM5, RNUM4)
    Next
End Sub
person actaram    schedule 25.03.2015
comment
см., что имя заголовка немного изменится с каждой загруженной электронной таблицей, скажем, название компании ... в другой электронной таблице может быть только компания, поэтому я не могу сделать это по имени заголовка. Это тот путь, который вы предложили? возможно ли как-то по-другому решить эту проблему - person Richard; 25.03.2015
comment
Затем сделайте это по индексу столбца. Например, вместо Cells("FirstColumn") можно легко сделать Cells(0). Если есть что-то еще, что я не принял во внимание, не стесняйтесь сказать мне. - person actaram; 25.03.2015
comment
да, я думал об этом, но также они могут быть в другом порядке при загрузке, поэтому ... вот почему я использовал Allowusertoordercolumns как true, чтобы упорядочить их и попытаться каким-то образом использовать displayindex для изменения индекса столбца - person Richard; 25.03.2015
comment
Хорошо, вы можете получить индекс столбца из отображаемого индекса столбца. Смотрите мою правку. - person actaram; 25.03.2015
comment
Кажется, я не могу заставить это работать правильно ... Что вы здесь делаете, так это получаете индекс столбца из индекса дисплея? Я получаю сообщение об ошибке, говорящее о том, что столбец DisplayIndex недоступен или не объявлен. Я пытаюсь запустить сопоставление с помощью кнопки, как только все столбцы были реорганизованы. - person Richard; 26.03.2015
comment
На самом деле этот запрос получает индексы столбцов первых отображаемых столбцов. Моя логика здесь заключается в том, что вы переупорядочили первые столбцы datagridview, чтобы его первые отображаемые столбцы соответствовали второму столбцу datagridview. Если это то, что вы делаете, опубликуйте код нажатия кнопки, чтобы я мог помочь вам в дальнейшем. - person actaram; 26.03.2015
comment
его эта строка Order By column.DisplayIndex).ToList() у меня проблема с тем, что он говорит, что столбец не объявлен или не находится в области видимости - person Richard; 27.03.2015
comment
Извините, я допустил ошибку, после предложения select столбец действительно больше не входит в область действия. Переместите порядок перед выбором. См. редактирование. - person actaram; 27.03.2015
comment
да, это идеально, также добавлено разделение, так как один из столбцов содержит имя контакта, которое иногда будет отображаться как имя и фамилия, но иногда только в одном столбце: d спасибо за помощь @bishopBarber - person Richard; 27.03.2015