Phantom cells in datagrids

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dave

    #1

    Phantom cells in datagrids

    Apologies if this has come up before, but I can't find it if it has. I
    am fairly new to .Net and am having problems with ghosts in the
    datagrid.

    Basically I have a find screen that accepts search criteria, then
    interrogates a database to find all matching records. These are put
    into a dataset, which has a dataview that is used as the datasource of
    my datagrid, which is read only. The idea is that the user selects
    which record they want to view.

    The good news is this all works - well apart from the ghost that is.
    Say I run a search that returns 10 records. These all show correctly
    in the grid. Say I click on row 9 to highlight it, then go and run a
    different search which returns just 5 records. They all display
    correctly in the datagrid, then there is a gap and then the previously
    highlighted cell remains, just hanging all by itself. It disappears
    when you select a real cell, but I can't find any way of getting rid of
    this 'ghost' programmaticall y. Any ideas?

    If it helps, this is the code I use to populate the datagrid...



    Dim conDatabase As New SqlClient.SqlCo nnection
    Dim commSQL As New SqlClient.SqlCo mmand
    Dim daSQL As New SqlClient.SqlDa taAdapter
    Dim dsData As New DataSet

    conDatabase.Con nectionString = strConnectionSt ring
    conDatabase.Ope n()
    commSQL.Connect ion = conDatabase
    commSQL.Command Type = CommandType.Sto redProcedure
    commSQL.Command Text = "usp_SearchBook s"
    ' Set parameters
    If Me.optTitleAll. Checked = False Then
    commSQL.Paramet ers.Add("@Title ", "%" &
    Me.txtTitle.Tex t.Trim & "%")
    End If
    If Me.optSeriesAll .Checked = False Then
    Dim clsComboClass As New ComboClass("", 0)
    clsComboClass =
    CType(Me.cboSer ies.Items(Me.cb oSeries.Selecte dIndex), ComboClass)
    commSQL.Paramet ers.Add("@Serie sID", clsComboClass.K eyValue)
    End If
    If Me.optAuthorAll .Checked = False Then
    commSQL.Paramet ers.Add("@Autho r", "%" &
    Me.txtAuthor.Te xt.Trim & "%")
    End If
    ' run search
    daSQL.SelectCom mand = commSQL
    daSQL.Fill(dsDa ta, "Table")

    ' Show match list in datagrid.
    Dim dvView As New DataView(dsData .Tables(0))
    dvView.RowState Filter = DataViewRowStat e.OriginalRows
    dvView.AllowNew = False
    Me.dgResults.Da taSource = dvView
    conDatabase.Clo se()



    Any help is greatly appreciated.

    Cheers

    Dave

  • Cor Ligthert [MVP]

    #2
    Re: Phantom cells in datagrids

    Dave,

    Can you try if it is returning *no* rows.

    In the datagrid is used internaly a try and catch to handle that, which is
    quiet anoying because it takes some time to find that the first time. So
    when you than click to quick than you maybe have this problem.

    Just a first thought reading your problem.

    Cor


    Comment

    • Dave

      #3
      Re: Phantom cells in datagrids

      Hi Cor

      If I run the second search with no results then the datagrid correctly
      shows 0 rows, but still shows the 'phantom' cell previously selected.
      In this case, with no actual rows to click, there is no way of clearing
      the phantom at all. Is this a bug in the datagrid itself?

      Cheers

      Dave

      Comment

      • Cor Ligthert [MVP]

        #4
        Re: Phantom cells in datagrids

        Dave,

        As far as I can see is there something strange in your code.

        You add the parameters by a selection.

        However than there should be to less parameters be added because if the
        checkbox is not checked, than I get the idea that you don't add a parameter.

        What do I see wrong (can be a message is not the easiest part to read code)?

        Cor


        Comment

        • Dave

          #5
          Re: Phantom cells in datagrids

          Hi Cor

          The stored procedure defaults all parameters to null, so any parameters
          I don't pass are treated as nulls and ignored by the SP. I have
          already established that the calls to the SP return the correct data -
          its just the behaviour of the datagrid that is giving me problems.

          Cheers

          Dave

          Comment

          • Cor Ligthert [MVP]

            #6
            Re: Phantom cells in datagrids

            Dave,

            I have never heard about phantom rows in the datagrid. Do you use a special
            painting of that.

            Did you check the amount of rowviews in your datasource in advance.
            something in a check as
            messagebox.show (dvView.rows.co unt.toString) when you set the datasource
            everytime.

            Cor


            "Dave" <davekeen@nildr am.co.uk> schreef in bericht
            news:1130166401 .440403.142940@ g43g2000cwa.goo glegroups.com.. .[color=blue]
            > Hi Cor
            >
            > The stored procedure defaults all parameters to null, so any parameters
            > I don't pass are treated as nulls and ignored by the SP. I have
            > already established that the calls to the SP return the correct data -
            > its just the behaviour of the datagrid that is giving me problems.
            >
            > Cheers
            >
            > Dave
            >[/color]


            Comment

            • Dave

              #7
              Re: Phantom cells in datagrids

              Hi

              I think I left too many distractions in my original question, so here
              is an easy way to reproduce the problem...

              Create a form and add a datagrid and 2 buttons to it. Cut and paste
              the following code and run it. As you see, the load event sets up the
              datagrid as I want it, with 2 columns, the first of which is 0 wide.
              The first button creates a dataset of 3 records and uses that as the
              source for the grid. If you click that you see the 3 rows fine.

              The second button does exactly the same thing but with only one record.
              If you click row 3 of the grid, then click button 2 you will see the
              third row of the OLD grid still displayed (my pkantom) along with the 1
              new row.



              Public Class Form1
              Inherits System.Windows. Forms.Form


              #Region " Windows Form Designer generated code "

              Public Sub New()
              MyBase.New()

              'This call is required by the Windows Form Designer.
              InitializeCompo nent()

              'Add any initialization after the InitializeCompo nent() call

              End Sub

              'Form overrides dispose to clean up the component list.
              Protected Overloads Overrides Sub Dispose(ByVal disposing As
              Boolean)
              If disposing Then
              If Not (components Is Nothing) Then
              components.Disp ose()
              End If
              End If
              MyBase.Dispose( disposing)
              End Sub

              'Required by the Windows Form Designer
              Private components As System.Componen tModel.IContain er

              'NOTE: The following procedure is required by the Windows Form
              Designer
              'It can be modified using the Windows Form Designer.
              'Do not modify it using the code editor.
              Friend WithEvents DataGrid1 As System.Windows. Forms.DataGrid
              Friend WithEvents Button1 As System.Windows. Forms.Button
              Friend WithEvents Button2 As System.Windows. Forms.Button
              <System.Diagnos tics.DebuggerSt epThrough()> Private Sub
              InitializeCompo nent()
              Me.DataGrid1 = New System.Windows. Forms.DataGrid
              Me.Button1 = New System.Windows. Forms.Button
              Me.Button2 = New System.Windows. Forms.Button
              CType(Me.DataGr id1,
              System.Componen tModel.ISupport Initialize).Beg inInit()
              Me.SuspendLayou t()
              '
              'DataGrid1
              '
              Me.DataGrid1.Da taMember = ""
              Me.DataGrid1.He aderForeColor =
              System.Drawing. SystemColors.Co ntrolText
              Me.DataGrid1.Lo cation = New System.Drawing. Point(381, 36)
              Me.DataGrid1.Na me = "DataGrid1"
              Me.DataGrid1.Si ze = New System.Drawing. Size(221, 409)
              Me.DataGrid1.Ta bIndex = 0
              '
              'Button1
              '
              Me.Button1.Loca tion = New System.Drawing. Point(101, 227)
              Me.Button1.Name = "Button1"
              Me.Button1.Size = New System.Drawing. Size(137, 70)
              Me.Button1.TabI ndex = 1
              Me.Button1.Text = "Button1"
              '
              'Button2
              '
              Me.Button2.Loca tion = New System.Drawing. Point(99, 360)
              Me.Button2.Name = "Button2"
              Me.Button2.Size = New System.Drawing. Size(140, 78)
              Me.Button2.TabI ndex = 2
              Me.Button2.Text = "Button2"
              '
              'Form1
              '
              Me.AutoScaleBas eSize = New System.Drawing. Size(5, 13)
              Me.ClientSize = New System.Drawing. Size(643, 510)
              Me.Controls.Add (Me.Button2)
              Me.Controls.Add (Me.Button1)
              Me.Controls.Add (Me.DataGrid1)
              Me.Name = "Form1"
              Me.Text = "Form1"
              CType(Me.DataGr id1,
              System.Componen tModel.ISupport Initialize).End Init()
              Me.ResumeLayout (False)

              End Sub

              #End Region

              Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
              System.EventArg s) Handles MyBase.Load
              '============== =============== =======
              ' Setup the style for the data grid.
              '============== =============== =======
              Dim dgtsTableStyle As New DataGridTableSt yle
              dgtsTableStyle. MappingName = "table"

              Dim column As New DataGridTextBox Column
              column.MappingN ame = "BookID"
              column.HeaderTe xt = "BookID"
              column.Width = 0
              column.ReadOnly = True
              dgtsTableStyle. GridColumnStyle s.Add(column)
              column.Dispose( )

              Dim column2 As New DataGridTextBox Column
              column2.Mapping Name = "Title"
              column2.HeaderT ext = "Title"
              column2.Width = 250
              column2.ReadOnl y = True
              dgtsTableStyle. GridColumnStyle s.Add(column2)

              Me.DataGrid1.Ta bleStyles.Add(d gtsTableStyle)
              End Sub

              Private Sub button1_Click(B yVal sender As System.Object, ByVal e As
              System.EventArg s) Handles Button1.Click
              '============== =============== =============== =============== ==
              ' Fill dataset with 3 records.
              '============== =============== =============== =============== ==
              Dim dsExample As New DataSet
              Dim tblTable As New DataTable("tabl e")

              '============== =============
              ' Set up dataset structure.
              '============== =============
              tblTable.Column s.Add("BookID",
              System.Type.Get Type("System.In t32"))
              tblTable.Column s.Add("Title",
              System.Type.Get Type("System.St ring"))
              dsExample.Table s.Add(tblTable)

              Dim ExampleRow As DataRow = dsExample.Table s("Table").NewR ow
              ExampleRow("Boo kID") = 1
              ExampleRow("Tit le") = "Little Women"
              dsExample.Table s("Table").Rows .Add(ExampleRow )

              Dim ExampleRow2 As DataRow = dsExample.Table s("Table").NewR ow
              ExampleRow2("Bo okID") = 2
              ExampleRow2("Ti tle") = "The Odessy"
              dsExample.Table s("Table").Rows .Add(ExampleRow 2)

              Dim ExampleRow3 As DataRow = dsExample.Table s("Table").NewR ow
              ExampleRow3("Bo okID") = 3
              ExampleRow3("Ti tle") = "Gone With the Wind"
              dsExample.Table s("Table").Rows .Add(ExampleRow 3)

              '============== ====
              ' Create dataview.
              '============== ====
              Dim dvView As New DataView(dsExam ple.Tables("Tab le"))
              dvView.AllowNew = False
              Me.DataGrid1.Da taSource = dvView
              End Sub

              Private Sub button2_Click(B yVal sender As System.Object, ByVal e As
              System.EventArg s) Handles Button2.Click
              '============== =============== =============== =============== ==
              ' Fill dataset with 1 record.
              '============== =============== =============== =============== ==
              Dim dsExample As New DataSet
              Dim tblTable As New DataTable("tabl e")

              '============== =============
              ' Set up dataset structure.
              '============== =============
              tblTable.Column s.Add("BookID",
              System.Type.Get Type("System.In t32"))
              tblTable.Column s.Add("Title",
              System.Type.Get Type("System.St ring"))
              dsExample.Table s.Add(tblTable)

              Dim ExampleRow As DataRow = dsExample.Table s("Table").NewR ow
              ExampleRow("Boo kID") = 9
              ExampleRow("Tit le") = "A Christmas Carol"
              dsExample.Table s("Table").Rows .Add(ExampleRow )

              '============== ====
              ' Create dataview.
              '============== ====
              Dim dvView As New DataView(dsExam ple.Tables("Tab le"))
              dvView.AllowNew = False
              Me.DataGrid1.Da taSource = dvView
              End Sub

              End Class


              That's about as clear as I can make it. I appreciate all your efforts
              on this, and hope this makes things easier for you.

              Many thanks

              Dave

              Comment

              • Cor Ligthert [MVP]

                #8
                Re: Phantom cells in datagrids

                Dave,

                It is definitly a bug in my opinion.

                As far as I can see is this one causing it
                column.ReadOnly = True

                Removing that one and set this to
                dvView.AllowEdi t = False

                Has in my opinion in the case of your sample the same effect in this case.

                It is in VS2005 working as it should

                I could not find it on MSDN as a bug, I have placed it as question on
                another place.

                I will try to tell my actions after this in this messagethread.

                Cor


                Comment

                • Bart Mermuys

                  #9
                  Re: Phantom cells in datagrids

                  Hi,

                  "Dave" <davekeen@nildr am.co.uk> wrote in message
                  news:1130179482 .852789.247560@ g49g2000cwa.goo glegroups.com.. .[color=blue]
                  > Hi
                  >
                  > I think I left too many distractions in my original question, so here
                  > is an easy way to reproduce the problem...
                  >
                  > Create a form and add a datagrid and 2 buttons to it. Cut and paste
                  > the following code and run it. As you see, the load event sets up the
                  > datagrid as I want it, with 2 columns, the first of which is 0 wide.
                  > The first button creates a dataset of 3 records and uses that as the
                  > source for the grid. If you click that you see the 3 rows fine.
                  >
                  > The second button does exactly the same thing but with only one record.
                  > If you click row 3 of the grid, then click button 2 you will see the
                  > third row of the OLD grid still displayed (my pkantom) along with the 1
                  > new row.
                  >[/color]

                  It does look like the bug descibed at the following link, if you assign
                  nothing as the DataSource the second time then the selected cell sticks too.
                  Microsoft Support is here to help you with Microsoft products. Find how-to articles, videos, and training for Microsoft Copilot, Microsoft 365, Windows 11, Surface, and more.


                  If you want all columns to be readonly then do what Cor said, otherwise you
                  could try to select the DataGrid before assigning a new DataSource, it seems
                  to help, eg:

                  Me.DataGrid1.Se lect()
                  Me.DataGrid1.Da taSource = dvView

                  HTH,
                  Greetings
                  [color=blue]
                  >
                  >
                  > Public Class Form1
                  > Inherits System.Windows. Forms.Form
                  >
                  >
                  > #Region " Windows Form Designer generated code "
                  >
                  > Public Sub New()
                  > MyBase.New()
                  >
                  > 'This call is required by the Windows Form Designer.
                  > InitializeCompo nent()
                  >
                  > 'Add any initialization after the InitializeCompo nent() call
                  >
                  > End Sub
                  >
                  > 'Form overrides dispose to clean up the component list.
                  > Protected Overloads Overrides Sub Dispose(ByVal disposing As
                  > Boolean)
                  > If disposing Then
                  > If Not (components Is Nothing) Then
                  > components.Disp ose()
                  > End If
                  > End If
                  > MyBase.Dispose( disposing)
                  > End Sub
                  >
                  > 'Required by the Windows Form Designer
                  > Private components As System.Componen tModel.IContain er
                  >
                  > 'NOTE: The following procedure is required by the Windows Form
                  > Designer
                  > 'It can be modified using the Windows Form Designer.
                  > 'Do not modify it using the code editor.
                  > Friend WithEvents DataGrid1 As System.Windows. Forms.DataGrid
                  > Friend WithEvents Button1 As System.Windows. Forms.Button
                  > Friend WithEvents Button2 As System.Windows. Forms.Button
                  > <System.Diagnos tics.DebuggerSt epThrough()> Private Sub
                  > InitializeCompo nent()
                  > Me.DataGrid1 = New System.Windows. Forms.DataGrid
                  > Me.Button1 = New System.Windows. Forms.Button
                  > Me.Button2 = New System.Windows. Forms.Button
                  > CType(Me.DataGr id1,
                  > System.Componen tModel.ISupport Initialize).Beg inInit()
                  > Me.SuspendLayou t()
                  > '
                  > 'DataGrid1
                  > '
                  > Me.DataGrid1.Da taMember = ""
                  > Me.DataGrid1.He aderForeColor =
                  > System.Drawing. SystemColors.Co ntrolText
                  > Me.DataGrid1.Lo cation = New System.Drawing. Point(381, 36)
                  > Me.DataGrid1.Na me = "DataGrid1"
                  > Me.DataGrid1.Si ze = New System.Drawing. Size(221, 409)
                  > Me.DataGrid1.Ta bIndex = 0
                  > '
                  > 'Button1
                  > '
                  > Me.Button1.Loca tion = New System.Drawing. Point(101, 227)
                  > Me.Button1.Name = "Button1"
                  > Me.Button1.Size = New System.Drawing. Size(137, 70)
                  > Me.Button1.TabI ndex = 1
                  > Me.Button1.Text = "Button1"
                  > '
                  > 'Button2
                  > '
                  > Me.Button2.Loca tion = New System.Drawing. Point(99, 360)
                  > Me.Button2.Name = "Button2"
                  > Me.Button2.Size = New System.Drawing. Size(140, 78)
                  > Me.Button2.TabI ndex = 2
                  > Me.Button2.Text = "Button2"
                  > '
                  > 'Form1
                  > '
                  > Me.AutoScaleBas eSize = New System.Drawing. Size(5, 13)
                  > Me.ClientSize = New System.Drawing. Size(643, 510)
                  > Me.Controls.Add (Me.Button2)
                  > Me.Controls.Add (Me.Button1)
                  > Me.Controls.Add (Me.DataGrid1)
                  > Me.Name = "Form1"
                  > Me.Text = "Form1"
                  > CType(Me.DataGr id1,
                  > System.Componen tModel.ISupport Initialize).End Init()
                  > Me.ResumeLayout (False)
                  >
                  > End Sub
                  >
                  > #End Region
                  >
                  > Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
                  > System.EventArg s) Handles MyBase.Load
                  > '============== =============== =======
                  > ' Setup the style for the data grid.
                  > '============== =============== =======
                  > Dim dgtsTableStyle As New DataGridTableSt yle
                  > dgtsTableStyle. MappingName = "table"
                  >
                  > Dim column As New DataGridTextBox Column
                  > column.MappingN ame = "BookID"
                  > column.HeaderTe xt = "BookID"
                  > column.Width = 0
                  > column.ReadOnly = True
                  > dgtsTableStyle. GridColumnStyle s.Add(column)
                  > column.Dispose( )
                  >
                  > Dim column2 As New DataGridTextBox Column
                  > column2.Mapping Name = "Title"
                  > column2.HeaderT ext = "Title"
                  > column2.Width = 250
                  > column2.ReadOnl y = True
                  > dgtsTableStyle. GridColumnStyle s.Add(column2)
                  >
                  > Me.DataGrid1.Ta bleStyles.Add(d gtsTableStyle)
                  > End Sub
                  >
                  > Private Sub button1_Click(B yVal sender As System.Object, ByVal e As
                  > System.EventArg s) Handles Button1.Click
                  > '============== =============== =============== =============== ==
                  > ' Fill dataset with 3 records.
                  > '============== =============== =============== =============== ==
                  > Dim dsExample As New DataSet
                  > Dim tblTable As New DataTable("tabl e")
                  >
                  > '============== =============
                  > ' Set up dataset structure.
                  > '============== =============
                  > tblTable.Column s.Add("BookID",
                  > System.Type.Get Type("System.In t32"))
                  > tblTable.Column s.Add("Title",
                  > System.Type.Get Type("System.St ring"))
                  > dsExample.Table s.Add(tblTable)
                  >
                  > Dim ExampleRow As DataRow = dsExample.Table s("Table").NewR ow
                  > ExampleRow("Boo kID") = 1
                  > ExampleRow("Tit le") = "Little Women"
                  > dsExample.Table s("Table").Rows .Add(ExampleRow )
                  >
                  > Dim ExampleRow2 As DataRow = dsExample.Table s("Table").NewR ow
                  > ExampleRow2("Bo okID") = 2
                  > ExampleRow2("Ti tle") = "The Odessy"
                  > dsExample.Table s("Table").Rows .Add(ExampleRow 2)
                  >
                  > Dim ExampleRow3 As DataRow = dsExample.Table s("Table").NewR ow
                  > ExampleRow3("Bo okID") = 3
                  > ExampleRow3("Ti tle") = "Gone With the Wind"
                  > dsExample.Table s("Table").Rows .Add(ExampleRow 3)
                  >
                  > '============== ====
                  > ' Create dataview.
                  > '============== ====
                  > Dim dvView As New DataView(dsExam ple.Tables("Tab le"))
                  > dvView.AllowNew = False
                  > Me.DataGrid1.Da taSource = dvView
                  > End Sub
                  >
                  > Private Sub button2_Click(B yVal sender As System.Object, ByVal e As
                  > System.EventArg s) Handles Button2.Click
                  > '============== =============== =============== =============== ==
                  > ' Fill dataset with 1 record.
                  > '============== =============== =============== =============== ==
                  > Dim dsExample As New DataSet
                  > Dim tblTable As New DataTable("tabl e")
                  >
                  > '============== =============
                  > ' Set up dataset structure.
                  > '============== =============
                  > tblTable.Column s.Add("BookID",
                  > System.Type.Get Type("System.In t32"))
                  > tblTable.Column s.Add("Title",
                  > System.Type.Get Type("System.St ring"))
                  > dsExample.Table s.Add(tblTable)
                  >
                  > Dim ExampleRow As DataRow = dsExample.Table s("Table").NewR ow
                  > ExampleRow("Boo kID") = 9
                  > ExampleRow("Tit le") = "A Christmas Carol"
                  > dsExample.Table s("Table").Rows .Add(ExampleRow )
                  >
                  > '============== ====
                  > ' Create dataview.
                  > '============== ====
                  > Dim dvView As New DataView(dsExam ple.Tables("Tab le"))
                  > dvView.AllowNew = False
                  > Me.DataGrid1.Da taSource = dvView
                  > End Sub
                  >
                  > End Class
                  >
                  >
                  > That's about as clear as I can make it. I appreciate all your efforts
                  > on this, and hope this makes things easier for you.
                  >
                  > Many thanks
                  >
                  > Dave
                  >[/color]


                  Comment

                  • Dave

                    #10
                    Re: Phantom cells in datagrids

                    Gentlemen, I am in your debt. Cor, as you quite rightly pointed out,
                    if I make the view read only then the problem goes away. In fact when
                    I do that, as soon as I shift focus off the datagrid the selected row
                    is unhighlighted anyway. That has fixed my problem

                    Bart, my problem sounds like it is related to the Microsoft description
                    and may well have the same route.

                    Anyway, all is now well with the world. Many thanks indeed :-)

                    Dave

                    Comment

                    Working...