Solved

how to maintain order in datagridview in vb.net

Posted on 2009-05-07
13
654 Views
Last Modified: 2012-05-06
Hi
I have a simple datagridview that is cleared with

DGV1.Rows.Clear()

and then updated on a timer with

For Each LC As DataStore In Update.APV.Values
DGV1.Rows.Add(New String() {DGVID, DGVWhen, DGVToGo})
Next

This works fine but If the user has changed the cell order in the columns, this is altered when the update takes place, as the order reverts back to the original.  Also the datagridview reverts back to cell 1,1

Is there a way of maintaining the cell order and cell position required by the user as the update takes place?

Thanks
0
Comment
Question by:PNRT
  • 5
  • 5
  • 3
13 Comments
 
LVL 15

Expert Comment

by:JackOfPH
ID: 24332476
I always used this method, to in sure that even the user change the order of the column, the code still inserting on the right cell.

'So instead of this...

For Each LC As DataStore In Update.APV.Values
    DGV1.Rows.Add(New String() {DGVID, DGVWhen, DGVToGo})
Next

I use:

For Each LC As DataStore In Update.APV.Values
Dim rowIndex as integer = DGV1.Rows.Add

DGV1(colDGVID.index, rowindex).value = DGVID
DGV1(colDGVWhen.index, rowindex).value = DGVWhen
DGV1(colDGVToGo.index, rowindex).value = DGVToGo

Next

Although this is longer compared to the code you are using right now, I am sure that even the user change the order of the column, the code still inserting on the right cell.

I hope I could help you,

Jack
'Suggested code:
 

For Each LC As DataStore In Update.APV.Values

Dim rowIndex as integer = DGV1.Rows.Add
 

DGV1(colDGVID.index, rowindex).value = DGVID

DGV1(colDGVWhen.index, rowindex).value = DGVWhen

DGV1(colDGVToGo.index, rowindex).value = DGVToGo
 

Next

Open in new window

0
 
LVL 2

Author Comment

by:PNRT
ID: 24333608
Thank you for your quick reply
I have tried the code as shown above, but it still does the same thing.   The column order still
reverts back to what it was before the user changed it, and also the highlighted row reverts
back to row 1.  This is the code I used.  I cant really see how this would maintain the order
required by the user.  Did I make my question clear that it is not incorrect cells that is the
problem, but keeping the same order of the cells in the column and also the
highlighted row kept in the same position and not moved back to row 1.  Many Thanks for
your help.

Private Sub UpdateDGV(ByVal DGVID As String, ByVal DGVWhen As String, ByVal DGVToGo As String)
        Dim rowIndex As Integer = DGV1.Rows.Add
        DGV1(Column1.Index, rowIndex).Value = DGVID
        DGV1(Column2.Index, rowIndex).Value = DGVWhen
        DGV1(Column3.Index, rowIndex).Value = DGVToGo
    End Sub
0
 
LVL 15

Expert Comment

by:JackOfPH
ID: 24333825
Does AllowColumnReorder is set to true?
0
 
LVL 15

Expert Comment

by:JackOfPH
ID: 24333845
Did you set the datagridview property AllowColumnReorder = True?

Try also this code snippet...
Private Sub UpdateDGV(ByVal DGVID As String, ByVal DGVWhen As String, ByVal DGVToGo As String)

        Dim selectedRowIndex as integer = 0

        Dim rowIndex As Integer = DGV1.Rows.Add

        If DGV1.SelectedRows.Count <> 0 thne

              SelectedRowIndex = DGV1.SelectedRows(0).index

        End If
 

        DGV1(Column1.Index, rowIndex).Value = DGVID

        DGV1(Column2.Index, rowIndex).Value = DGVWhen

        DGV1(Column3.Index, rowIndex).Value = DGVToGo
 

        DGV1.Rows(SelectedRowIndex).Selected  = True

    End Sub

Open in new window

0
 
LVL 2

Author Comment

by:PNRT
ID: 24334323
Thank you very much for replying so quickly, unfortuantely still the same problem.

Is the problem perhaps in the way I am clearing DGV1 in the first place ie
 DGV1.Rows.Clear()
Could that be the problem?

AllowUserToOrderColumns is set to True
This is the code so far

Private Sub UpdateDGV(ByVal DGVID As String, ByVal DGVWhen As String, ByVal DGVToGo As String)
        Dim selectedRowIndex As Integer = 0
        Dim rowIndex As Integer = DGV1.Rows.Add
        If DGV1.SelectedRows.Count <> 0 Then
            selectedRowIndex = DGV1.SelectedRows(0).Index
        End If
        DGV1(Column1.Index, rowIndex).Value = DGVID
        DGV1(Column2.Index, rowIndex).Value = DGVWhen
        DGV1(Column3.Index, rowIndex).Value = DGVToGo
        DGV1.Rows(selectedRowIndex).Selected = True
End Sub
0
 
LVL 15

Expert Comment

by:JackOfPH
ID: 24334340
Put this code after you clear the contents of the Datagridview.

  Dim selectedRowIndex As Integer = 0
        If DGV1.SelectedRows.Count <> 0 Then
            selectedRowIndex = DGV1.SelectedRows(0).Index
  End If


Then put this after you update all the contents of the datagridview...


DGV1.Rows(selectedRowIndex).Selected = True
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 2

Author Comment

by:PNRT
ID: 24334588
Still the same unfortunately.

Just to experiment,  I started a new project just with a timer and a Datagridview, the code is below.
This has the same problem.  Ist column goes back to original order and highlighted row moves to 1

Imports System.Data.OleDb

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        Timer1.Interval = 5000
        DGV1.Rows.Clear()
        Dim selectedRowIndex As Integer = 0
        If DGV1.SelectedRows.Count <> 0 Then
            selectedRowIndex = DGV1.SelectedRows(0).Index
        End If

        Dim i As Integer
        For i = 1 To 20

            dgvid = i
            dgvwhen = ""
            dgvtogo = ""
           
            DGV1.AllowUserToOrderColumns = True
            Dim rowIndex As Integer = DGV1.Rows.Add
            If DGV1.SelectedRows.Count <> 0 Then
                selectedRowIndex = DGV1.SelectedRows(0).Index
            End If
            DGV1(Column1.Index, rowIndex).Value = dgvid
            DGV1(Column2.Index, rowIndex).Value = dgvwhen
            DGV1(Column3.Index, rowIndex).Value = dgvtogo
            DGV1.Rows(selectedRowIndex).Selected = True
        Next
    End Sub
0
 
LVL 15

Expert Comment

by:JackOfPH
ID: 24341471
Try this one...
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
 

        Timer1.Interval = 5000
 

Dim selectedRowIndex As Integer = 0

        If DGV1.SelectedRows.Count <> 0 Then

            selectedRowIndex = DGV1.SelectedRows(0).Index

        End If

        DGV1.Rows.Clear()

        
 

        Dim i As Integer

        For i = 1 To 20
 

            dgvid = i

            dgvwhen = ""

            dgvtogo = ""

           

            DGV1.AllowUserToOrderColumns = True

            Dim rowIndex As Integer = DGV1.Rows.Add

            If DGV1.SelectedRows.Count <> 0 Then

                selectedRowIndex = DGV1.SelectedRows(0).Index

            End If

            DGV1(Column1.Index, rowIndex).Value = dgvid

            DGV1(Column2.Index, rowIndex).Value = dgvwhen

            DGV1(Column3.Index, rowIndex).Value = dgvtogo

            

        Next

DGV1.Rows(selectedRowIndex).Selected = True

    End Sub

Open in new window

0
 
LVL 2

Author Comment

by:PNRT
ID: 24343596
Hi again
Sorry but still the same thing.
Are we understanding the same problem in this question?
With the program at present, column 1 is populated  1 to 20.  
When I click on the column header the order changes to 20 to 1.  
When I click on say cell 5, that cell becomes highlighted.  
This is all corect.  
However, when the next update takes place, the order reverts back to 1 to 20 and the highlighted
cell becomes 1 again.  
Im trying to get it so that the column order remailns the same and the highlighted cell and position remain the same.

Is that OK?

Many Thanks
0
 
LVL 3

Expert Comment

by:Kevin Robinson
ID: 24358933
"Is there a way of maintaining the cell order and cell position required by the user as the update takes place?"

Yes of course.  I am working on this at the minute and is not as hard as i sounds.  My code is not quite finished but you could set a property of my control to a user setting of your application. This would alllow you user to select the columns they want to see, the width and the positions of the columns This would be loaded back every time the app is started.
0
 
LVL 2

Author Comment

by:PNRT
ID: 24472617

I didnt hear back from anyone as yet?   Perhaps this is not possible?

0
 
LVL 3

Accepted Solution

by:
Kevin Robinson earned 250 total points
ID: 24472701

I am using a custom collection to hold the info about the columns.  There is a datagrid view column collection but certain properties are readonly (for good reason), I just found it easier to make my own.  You can create a setting in your applcaiton for each of your  datagrids.  This means that each user can setup each the grisds the way they want.
 
 

Public Class Kevs_Column
 

#Region "Properties"

    Private M_ColumnName As String = ""

    Public Property ColumnName() As String

        Get

            Return Me.M_ColumnName

        End Get

        Set(ByVal value As String)

            Me.M_ColumnName = value

        End Set

    End Property
 

    Private M_ColumnWidth As Integer = 0

    Public Property ColumnWidth() As Integer

        Get

            Return Me.M_ColumnWidth

        End Get

        Set(ByVal value As Integer)

            Me.M_ColumnWidth = value

        End Set

    End Property
 

    Private M_ColumnPosition As Integer = 0

    Public Property ColumnPosition() As Integer

        Get

            Return Me.M_ColumnPosition

        End Get

        Set(ByVal value As Integer)

            Me.M_ColumnPosition = value

        End Set

    End Property
 

    Private M_Visible As Boolean = True

    Public Property Visible() As Boolean

        Get

            Return Me.M_Visible

        End Get

        Set(ByVal value As Boolean)

            Me.M_Visible = value

        End Set

    End Property

#End Region
 

#Region "Constructors"

    Public Sub New(ByVal ColumnName As String, ByVal ColumnPosition As Integer, ByVal ColumnWidth As Integer, ByVal Visible As Boolean)

        Me.M_ColumnName = ColumnName

        Me.M_ColumnPosition = ColumnPosition

        Me.M_ColumnWidth = ColumnWidth

        Me.Visible = Visible

    End Sub

#End Region
 

End Class
 

Public Class Kevs_ColumnCollection

    Private M_Columns As New List(Of Kevs_Column)

    Public Property Columns() As List(Of Kevs_Column)

        Get

            Return Me.M_Columns

        End Get

        Set(ByVal value As List(Of Kevs_Column))

            Me.M_Columns = value

        End Set

    End Property
 

    Public ReadOnly Property Count() As Integer

        Get

            Return Me.M_Columns.Count

        End Get

    End Property
 
 

    Public Sub Add(ByVal Column As Kevs_Column)

        Me.M_Columns.Add(Column)

    End Sub
 

    Public Sub Add(ByVal ColumnName As String, ByVal ColumnPosition As Integer, ByVal ColumnWidth As Integer, ByVal Visible As Boolean)

        Dim col As New Kevs_Column(ColumnName, ColumnPosition, ColumnWidth, Visible)

        Me.M_Columns.Add(col)

    End Sub
 
 

    Public Sub Clear()

        Me.Columns.Clear()

    End Sub
 

End Class
 
 
 

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Create a new custom control and inherit the datagrid view then add the following code.
 
 

 Private cols As New Kevs_ColumnCollection
 

    Public Sub SaveColumns(Setting as As New Kevs_ColumnCollection)

        Dim ColumnCount As Integer = 0

        ColumnCount = Me.dg_Contacts.ColumnCount
 

        For i As Integer = 0 To ColumnCount - 1

            cols.Clear()

            cols.Add(Me.dg_Contacts.Columns(i).Name, Me.dg_Contacts.Columns(i).Index, Me.dg_Contacts.Columns(i).Width, Me.dg_Contacts.Columns(i).Visible)

        Next
 

        Try

               My.Settings(Setting) = cols

        Catch ex As Exception

            MsgBox(ex.Message)

        End Try
 

    End Sub
 

    Public Sub RestoreColumns(Setting as String)

        Try

            Dim Restorecols As New Kevs_ColumnCollection

                    Restorecols = My.Settings(Setting)

                    Restorecols = CType(Restorecols, Kevs_ColumnCollection)

                    If Restorecols.Count <> 0 Then

                        For i As Integer = 0 To cols.Count - 1

                            Me.dg_Contacts.MoveColumn(cols.Columns(i).ColumnName, cols.Columns(i).ColumnPosition)

                            Me.dg_Contacts.SetColumnWidth(cols.Columns(i).ColumnName, cols.Columns(i).ColumnWidth)

                            Me.dg_Contacts.Columns(i).Visible = Restorecols.Columns(i).Visible

                        Next

                    End If

          Catch ex As Exception

            MsgBox(ex.Message)

        End Try

    End Sub

Open in new window

0
 
LVL 3

Expert Comment

by:Kevin Robinson
ID: 24480989
Did that work ok for you?
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

912 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now