none
сортировка в DataGridView RRS feed

  • Вопрос

  • Visual Studio 2010, Visual Basic, WinForm

    Здравствуйте. На форме DataGridView привязан програмно к  DataSet.  При выборе строки в DataGridView номер активной строки получаю так:

    FormMain.dgvFormMain.Rows.GetFirstRow(DataGridViewElementStates.Selected)
    Но, если воспользоваться стандартной сортировкой DataGridView данный способ получения выбранной после сортировки строки не работает, т.е. выдает ошибочный номер строки. Как можно исправить проблему?


    • Изменено Igor Galyaev 30 марта 2017 г. 20:17
    30 марта 2017 г. 20:17

Ответы

  • Отключать - после того, как столбцы создаются.

    Если столбцы созданы в конструкторе - там же в конструкторе такая настройка должна быть.

    Если столбцы автоматически генерируются из источника данных - после присвоения свойства DataSource. 

    • Помечено в качестве ответа Igor Galyaev 3 апреля 2017 г. 19:38
    3 апреля 2017 г. 19:14

Все ответы

  • Как вы уже поняли это индексы не одинаковы и их нельзя использовать таким образом.

    Как исправить: не использовать индексы таким образом.

    Что именно делать зависит от того что вы делели с этими индексами. Например если вы хотите получить DataRow из вашего DataSet, то наверное можно использовать DataBoundItem:

    https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewrow.databounditem(v=vs.110).aspx

    В противном случае уточните что именно вы делайте.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    30 марта 2017 г. 21:05
    Модератор
  • Спасибо, посмотрю DataBoundItem. В общем, мне нужен только индекс строки, далее я получаю все необходимые данные по этому индексу из DataSet для заполнения загружаемой формы, например:

    'i - числовая переменная
    ComboBoxName.Text = FormMain.m_DS.Tables("Patient").Rows(i).Item("NamePatient").ToString

    Если не использовать сортировку DataGridView все работает четко; сортировка мне не нужна, но как её отключить я не нашел, это тоже приемлемый вариант решения.

    2 апреля 2017 г. 9:30
  • Индексы могут не соответствовать и без сортировки, например при удалении/добавлении. Поэтому так делать нельзя, даже если сортировку отключить. 

    Опять же, судя по описанию то что вы делайте вообще не требует кода, можно сделать это привязками даже в Forms:

    https://msdn.microsoft.com/en-us/library/y8c0cxey(v=vs.110).aspx


    This posting is provided "AS IS" with no warranties, and confers no rights.

    2 апреля 2017 г. 15:14
    Модератор
  • "cортировка мне не нужна, но как её отключить я не нашел"

    если имеется в виду сортировка по нажатию заголовка столбца, установить у DataGridViewColumn свойство SortMode в NotSortable


    • Изменено VadimTagil 2 апреля 2017 г. 15:46
    2 апреля 2017 г. 15:46
  • Загрузка главной формы и привязка организованы примерно так:

    Public m_DS, ds As New DataSet()
    Public da1 As New OleDbDataAdapter
    Public m_dv1 As DataView
    Public WithEvents m_cm1 As CurrencyManager
    
    LoadTable("TabPatient", "SELECT * FROM TabPatient", m_dt1, m_da1)
    
    Public Sub LoadTable(ByVal tabname As String, ByVal sel As String, ByRef dt As DataTable, ByRef da As OleDbDataAdapter)
            Dim connstr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=baza\" + BazaName
            Dim conn As New OleDbConnection(connstr)
            da = New OleDbDataAdapter(sel, connstr)
            ' Создать INSERT, UPDATE, and DELETE команды.
            Dim cmdb As New OleDbCommandBuilder(da) 
            Try
                da.InsertCommand = cmdb.GetInsertCommand() 
                da.UpdateCommand = cmdb.GetUpdateCommand() 
                da.DeleteCommand = cmdb.GetDeleteCommand() 
            Catch exc As Exception
                MsgBox(exc.Message)
            End Try
            da.TableMappings.Add("Table", tabname)
            ' Load the DataSet.
            da.Fill(m_DS)
            ' Save a reference to the new table.
            dt = m_DS.Tables(tabname)
    End Sub
    
    'tabPacient
            m_dv1 = New DataView(m_dt1)
            dgvFormMain.DataSource = m_dv1
            m_cm1 = CType(Me.BindingContext(m_dt1), CurrencyManager)
    при удалении/добавлении строки в DataGridView индекс, получаемый описанным вариантом не меняется.  С DataBoundItem не совсем понял, как это применить в моем случае. Буду благодарен за пример кода.

    2 апреля 2017 г. 17:04
  • если имеется в виду сортировка по нажатию заголовка столбца, установить у DataGridViewColumn свойство SortMode в NotSortable

    Да, именно эту сортировку я имею ввиду, но в конструкторе формы у DataGridView нет пункта, регулирующего сортировку, а в коде выдает ошибку

    если согласиться на замену, как предлагает VS, все равно выдает ошибку

    2 апреля 2017 г. 19:48
  • не знаю VB, в C# делается так:

    dgvT.SortMode=DataGridViewColumnSortMode.NotSortable;


    3 апреля 2017 г. 3:02
  • Этот вариант в принципе работает, спасибо, наметился прогресс:

     Private Sub dgvFormMain_Sorted(sender As Object, e As System.EventArgs) Handles dgvFormMain.Sorted
            Dim dgvT As DataGridViewColumn
            Dim nCol As Integer = dgvFormMain.Columns.Count - 1
            For nCol = 0 To nCol
                dgvT = dgvFormMain.Columns(nCol)
                dgvT.SortMode = DataGridViewColumnSortMode.NotSortable
            Next
        End Sub
    Вопрос, где и как именно отключать сортировку. В моем примере сортировка действительно становится недоступной, но после первого щелчка по столбцу, т.е. один раз сортировка происходит. Пробовал данный код вставлять непосредственно при загрузке основной формы, но результат тот же. Подскажите, как вы реализуете такую блокировку?

    3 апреля 2017 г. 16:15
  • Отключать - после того, как столбцы создаются.

    Если столбцы созданы в конструкторе - там же в конструкторе такая настройка должна быть.

    Если столбцы автоматически генерируются из источника данных - после присвоения свойства DataSource. 

    • Помечено в качестве ответа Igor Galyaev 3 апреля 2017 г. 19:38
    3 апреля 2017 г. 19:14
  • Мне странно что вы не въехали в ту же проблему при удалении строки. Ведь строка фактически не удаляется, а помечается как удаленная чтоб знать какую команду удаления из базы затем нужно выполнить. Как вы понимайте при этом строк на экране становится на одну меньше, а полное число строк в источнике не меняется и индексы перестают соответсвовать.

    Примерно такая же интесность может происходить при добавлении строк, но там все несколько сложнее так как имеется временная строка.

    В любом случае вы не туда копайте, надо чинить заведомо проблематичный код, а не пытатся подлатать его чтоб было несколько сложнее его поломать.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    3 апреля 2017 г. 19:40
    Модератор
  • Поместил код после присвоения свойства DataSource, работает!!!

    Спасибо за участие. Теперь буду искать правильный вариант получения индекса выбранной в DataGridView строки.

    3 апреля 2017 г. 19:42
  • Удаленные строки не влияют, если пользоваться DefaulView вместо самой таблицы. Но вообще-то да, через привязки это реализуется куда лучше.
    4 апреля 2017 г. 3:19