views:

2089

answers:

2

I have several problems with rows in a DataGridView.

Background information: The DataGridView (DataGridViewCalib) is in one TabPage of a TabControl, some columns of the DataGridView are automatically DataGridViewCheckBoxColumn as the DataSource have some colums which are Boolean. This is a Windows Form written in VB.Net with Visual Studio 2008. The user loads an input data file.

The problems:

1) At first arrival in the TabPage, ShowDataGridViewCalib (code below) is called. All rows are then shown in the DataGridView, despite the code saying that some rows should not be visible. Breakpoints in the code show that the code do arrive at the Rows.Visible = False events. Despite all rows beeing shown a Watch in the debugger shows that:

DataGridViewCalib.DisplayedColumnCount(True)=0
DataGridViewCalib.DisplayedColumnCount(False=0)
DataGridViewCalib.DisplayedRowCount(True)=0 
DataGridViewCalib.DisplayedRowCount(False)=0

Columns.Visible=False works as expected.

When running the subroutine ShowDataGridViewCalib a second time, by enforcing it from the checkbox CbUniform, the reduction in the number of rows works as it should, and the DataGridViewCalib.Displayed...Count is correct.

What causes the whole DataTable to be shown the first time?

2) The user can load another input data file. When a second input file is loaded and ShowDataGridViewCalib is run, another strange thing occur. DataGridViewCalib.DataSource = {System.Data.DataTable} and this DataTable has the same properties as dtCatchCalib, but

DataGridViewCalib.Columns.Count = 0 
DataGridViewCalib.Rows.Count =  0

and nothing is shown in the DataGridView. Before the second input file is loaded most of the data is cleared, including DataGridViewCalib.Columns.Clear() and dtCatchCalib.Clear(). Especially for this second problem I assume that the error might be somewhere outside of ShowDataGridViewCalib, but I would be very happy for hints about what causes the DataGridView to have a DataSource but still no rows and columns.

The code:

    Private Sub ShowDataGridViewCalib()
    '[...]
                Dim kolwidth As Integer = 77
                DataGridViewCalib.DataSource = dtCatchCalib
                DataGridViewCalib.Refresh()
                Dim kol As DataGridViewColumn
                For Each kol In DataGridViewCalib.Columns
                    kol.SortMode = DataGridViewColumnSortMode.NotSortable
                    If CbUniform.Checked = False Then
                        kol.Visible = True
                        kol.Width = kolwidth
                        If kol.Name = "CatchmentID" Then
                            kol.ReadOnly = True
                        ElseIf kol.Name = "parc0" Then
                            kol.HeaderText = "c0"
                        ElseIf kol.Name = "statr" Then
                            kol.Visible = False
                            kol.ReadOnly = True
                            kol.HeaderText = "r"
                        End If
                    Else
                        If kol.Name = "IncludeObs" Then
                            kol.Width = kolwidth
                        ElseIf kol.Name = "CatchmentID" Then
                            kol.ReadOnly = True
                            kol.Width = kolwidth
                        Else
                            kol.Visible = False
                        End If
                    End If
                Next

                'Dim rad As DataGridViewRow
                'Dim dum As Integer
                'dum = 0
                'For Each rad In DataGridViewCalib.Rows
                '    dum += 1                                        ' # rows in dtCatchCalib is = # subcatchments
                '    DataGridViewCalib.CurrentCell = Nothing         ' Unselect the current cell, needed to be able to set the row invisible
                '    rad.Visible = False                             ' TEST
                '    If ObsLst(dum) = True Then                      ' ObsLst have its first value at index 1
                '        rad.Visible = True
                '    Else
                '        DataGridViewCalib.CurrentCell = Nothing     ' Unselect the current cell, needed to be able to set the row invisible
                '        rad.Visible = False
                '    End If
                'Next

                For i = 0 To dtCatchCalib.Rows.Count - 1
                    DataGridViewCalib.CurrentCell = Nothing
                    DataGridViewCalib.Rows(i).Visible = False
                    If ObsLst(i+1) = True Then                      ' ObsLst have its first value at index 1
                        DataGridViewCalib.Rows(i).Visible = True
                    Else
                        DataGridViewCalib.CurrentCell = Nothing
                        DataGridViewCalib.Rows(i).Visible = False
                    End If

                Next


'[...]
    End Sub

There are two alternative ways of handling the rows in the code. The first attempt (commented away here) is probably the "nicest".

This is the first time I post a question to a programming forum. Please ask me again if I did not express me cleary enough.

A: 

I still have no clue why the program behaved as described, but I do now have a workaround. The DataTable I am displaying is anyhow a temporary DataTable, combining columns from two different DataTables that I would actually like to show. Thus I removed the rows already from this temporary DataTable, instead of doing it through the DataGridView. Through the CellValueChanged event I'm passing on the changes in the temporary DataTable to the original DataTables.

The Nile
A: 

The second problem I solved by also setting

DataGridViewCalib.DataSource=Nothing

when I cleared the forms and the data before loading a new file.

I have also got an additonal reply here http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/27e46f65-f27b-4f24-805f-209f02b29574

from Aland Li, saying

Based on your description, the two issues have a common feature: we did set the Visible property but it did not react. The cause is mostly that the data source is bound again after we set the Visible property of the rows in the DataGridView. For example, we set all the rows invisible by setting the Visible property of them to false and expect they are hidden. But the data source might be bound again after we set the Visible property and the rows are recreated. The old rows are disposed so the setting would not make react. The new rows are initialized and their Visible property are true. So the rows are still visible. You can trace the data source binding by track the DataBindingComplete event. You can add a handler to that event and show some message. Then you would know if the data source is bound again.

The Nile

The Nile