Avatar of Dodsworth
Dodsworth
 asked on

AJAX style Rating control in a DataGridView Column

As the title says, i'd like to display an AJAX style Rating control in a DataGridView Column.
It doesn't have to 'do' anything... Just display 'Stars'.

Currently my DGV is bound to a table that stores the rating as a string of one to five asterisks .  
Problem is that I want nice big stars rather than oddly aligned asterisks !

Any ideas ?
Visual Basic.NET

Avatar of undefined
Last Comment
Jorge Paulino

8/22/2022 - Mon
Jorge Paulino

Dodsworth

ASKER
Ah ha !

I searched for ages to find a link like that !
The reason I failed to find i was that I included 'vb.net' in the search.  Could you VBificate it ?
ASKER CERTIFIED SOLUTION
Jorge Paulino

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Dodsworth

ASKER
Right.  How do I add a new column and bind it to my data ?
Your help has saved me hundreds of hours of internet surfing.
fblack61
Jorge Paulino

That I never done it. I just made this changes for you.

I have to look if that's possible or easy handle, but not now. I will try later.
Dodsworth

ASKER
From the example I look at the columns collection and see that the ColumnType property is set to RatingColumn.

I can't find a language reference to ColumnType tho.

Any ideas ?
Jorge Paulino

>> I can't find a language reference to ColumnType tho.

What do you mean with this ? RatingColumn it's build in the code, you don't have language reference.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Jorge Paulino

It's a custom column type ...
Dodsworth

ASKER
Yes if I want to add a rating column in code, say...

Dim myColumn as New DataColumn

Where is the

myColumn.ColumnType

So that I can set the type to be a ratingcolumn ?
Jorge Paulino

To insert the column on the right side of a bound datagridview you can use:
        Dim myRatingColumn As New CustomDataGridViewColumn.RatingColumn
        With myRatingColumn
            .HeaderText = "Rating System"
        End With
        Me.DataGridView1.Columns.Insert(Me.DataGridView1.ColumnCount, myRatingColumn)

Open in new window

Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
Dodsworth

ASKER
Ok I have an empty column now.

How do I bind it ?
Jorge Paulino

As I already post it, it's not easy to bind it with a datasource.

The better method (i think) it to bind with a datasource and then add the column. After this you check when the user changes the rate and you write it on you bound column. It's a workaround that should work fine with some work and validations

Dodsworth

ASKER
ok I have my rating (number) bound column.

How do I set the number of stars in the unbound col ?
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Jorge Paulino

You have some columns bound to a datasource and you have added one extra column for the rating. Now you want to show the number of start acording with the bould column, right ?

That's allot of work for only 125 points :)
Dodsworth

ASKER
I assume I'd set the stars on the cellformat event.

But what is the 'star setting' syntax ?
Dodsworth

ASKER
500 greedy but excellent one !
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Jorge Paulino

One final thing: do you bind the datagridview using code or by the wizards ?
Dodsworth

ASKER
I don't suppose that I 'bind' really...

I 'fill' like.......

Public Sub fillGrid(ByVal dg As DataGridView, ByVal strSQL As String)
        Dim Ds As DataSet
        Dim cmd As New OleDb.OleDbCommand(strSQL, New OleDb.OleDbConnection(ConnString))
        Dim da As New OleDb.OleDbDataAdapter

        da.SelectCommand = cmd
        Ds = New DataSet
        da.Fill(Ds)
        dg.DataSource = Ds.Tables(0)
        da = Nothing
        Ds = Nothing
        cmd = Nothing
    End Sub

and then set column properties.
Jorge Paulino

Ok, lets try this code:
Imports System.Data.SqlClient
 
Public Class Form1
 
    Const ratingBoundColumn As Byte = 3
 
    Private ratingColumn As Byte
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        Application.EnableVisualStyles()
        Me.DataGridView1.SuspendLayout()
 
        ' Fill the datagridview (example)
        Dim myConnectionString As String = _
            "Data Source=.\SQLEXPRESS;AttachDbFilename='c:\myDatabase.mdf';" & _
            ";Integrated Security=True;User Instance=True"
        Try
 
            Dim connection As New SqlConnection(myConnectionString)
            Dim SQL As String = "SELECT * FROM myTable;"
 
            Dim da As New SqlDataAdapter(SQL, connection)
            Dim ds As New DataSet
 
            da.Fill(ds, "myTable")
            Me.DataGridView1.DataSource = ds.Tables("myTable").DefaultView
 
            connection.Close()
            connection = Nothing
 
        Catch ex As Exception
            MessageBox.Show(ex.Message, My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
 
 
        ' Adds the new column to the datagridview
        Dim myRatingColumn As New CustomDataGridViewColumn.RatingColumn
        myRatingColumn.HeaderText = "Rating System"
        Me.DataGridView1.Columns.Insert(Me.DataGridView1.ColumnCount, myRatingColumn)
 
        ' Checks the number of the Rating Column
        ratingColumn = Me.DataGridView1.ColumnCount - 1
 
        ' Loop on all rows as sets the value on the stars
        For Each row As DataGridViewRow In Me.DataGridView1.Rows
            If Not row.IsNewRow Then
                Dim rc As DataGridViewImageCell
                rc = (CType(Me.DataGridView1(ratingColumn, row.Index), DataGridViewImageCell))
                rc.Value = row.Cells(ratingBoundColumn).Value
            End If
        Next
 
        ' You can uncomment the next row after tests
        ' It's to hide de rating bound column
        Me.DataGridView1.Columns(ratingBoundColumn).Visible = False
 
        Me.DataGridView1.ResumeLayout()
 
    End Sub
 
 
    ' Each time you change a star it will write on the bound column
    Private Sub DataGridView1_CellContentClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
        If e.ColumnIndex = ratingColumn And e.RowIndex <> -1 Then
            Dim rc As DataGridViewImageCell
            rc = (CType(Me.DataGridView1(ratingColumn, e.RowIndex), DataGridViewImageCell))
            If rc.Value <> Me.DataGridView1(ratingBoundColumn, e.RowIndex).Value Then
                Me.DataGridView1(ratingBoundColumn, e.RowIndex).Value = rc.Value
            End If
        End If
    End Sub
 
   
End Class

Open in new window

⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Dodsworth

ASKER
Pasted your code and hooked up the DB...

Data but no Stars !
Jorge Paulino

Is this value right ?

Const ratingBoundColumn As Byte = 3
Dodsworth

ASKER
Yes.
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
Jorge Paulino

Ok, here you have another example with an unbound datagridview. It works fine with bound or unbound datagrids
Imports System.Data.SqlClient
 
Public Class Form1
 
    Const ratingBoundColumn As Byte = 2
    Private ratingColumn As Byte
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        Application.EnableVisualStyles()
        Me.DataGridView1.SuspendLayout()
 
        Dim dt As New DataTable
        dt.Columns.Add("ID")
        dt.Columns.Add("Description")
        dt.Columns.Add("Rank")
 
        Dim dr As DataRow
        Dim rnd As New Random
 
        For x As Byte = 0 To 100
            dr = dt.NewRow
            dr.Item("ID") = x.ToString
            dr.Item("Description") = "Item " & x.ToString
            dr.Item("Rank") = rnd.Next(1, 5)
            dt.Rows.Add(dr)
        Next
 
        Me.DataGridView1.DataSource = dt
 
        ' Adds the new column to the datagridview
        Dim myRatingColumn As New CustomDataGridViewColumn.RatingColumn
        myRatingColumn.HeaderText = "Rating System"
        Me.DataGridView1.Columns.Insert(Me.DataGridView1.ColumnCount, myRatingColumn)
 
        ' Checks the number of the Rating Column
        ratingColumn = Me.DataGridView1.ColumnCount - 1
 
        ' Loop on all rows as sets the value on the stars
        For Each row As DataGridViewRow In Me.DataGridView1.Rows
            If Not row.IsNewRow Then
                Dim rc As DataGridViewImageCell
                rc = (CType(Me.DataGridView1(ratingColumn, row.Index), DataGridViewImageCell))
                rc.Value = row.Cells(ratingBoundColumn).Value
            End If
        Next
 
        ' You can uncomment the next row after tests
        ' It's to hide de rating bound column
        Me.DataGridView1.Columns(ratingBoundColumn).Visible = False
 
        Me.DataGridView1.ResumeLayout()
 
    End Sub
 
 
    ' Each time you change a star it will write on the bound column
    Private Sub DataGridView1_CellContentClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
        If e.ColumnIndex = ratingColumn And e.RowIndex <> -1 Then
            Dim rc As DataGridViewImageCell
            rc = (CType(Me.DataGridView1(ratingColumn, e.RowIndex), DataGridViewImageCell))
            If rc.Value <> Me.DataGridView1(ratingBoundColumn, e.RowIndex).Value Then
                Me.DataGridView1(ratingBoundColumn, e.RowIndex).Value = rc.Value
            End If
        End If
    End Sub
   
End Class

Open in new window

Dodsworth

ASKER
Still no stars !

Could the rating class be wrong ?
Jorge Paulino

Give a minute I will upload an example.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Jorge Paulino

Dodsworth

ASKER
Ooops.  I added the resources incorrectly.

Your earlier post worked fine after all !
Jorge Paulino

The "greedy" one as helped you on this. It's not a question of points but to be fair.

Glad I could help you and good luck

jpaulino
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck