?
Solved

Change Row Color (not at drawing time)

Posted on 2004-11-19
3
Medium Priority
?
178 Views
Last Modified: 2008-01-09
Hi,
I want to list items in a control. This list will be use for a verification process.

I want to change the color of a row (1) in green when the user scan the rigth thing and red in the other case.

I'm trying to find the way to do it with Dataset, wiht no clue.
The only code I've found is at the drawing time of the dataset.

Thanks for your help, and if you think that's better to use another control, I will appreciate.
0
Comment
Question by:CharlesD
1 Comment
 
LVL 28

Accepted Solution

by:
iboutchkine earned 1000 total points
ID: 12629144
Play with it


Form1
=====
Imports System.Data.OleDb
Imports System.Runtime.InteropServices

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.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() 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.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    '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 DataGrid2 As System.Windows.Forms.DataGrid
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.DataGrid1 = New System.Windows.Forms.DataGrid
        Me.DataGrid2 = New System.Windows.Forms.DataGrid
        CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.DataGrid2, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'DataGrid1
        '
        Me.DataGrid1.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.DataGrid1.DataMember = ""
        Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
        Me.DataGrid1.Location = New System.Drawing.Point(16, 24)
        Me.DataGrid1.Name = "DataGrid1"
        Me.DataGrid1.Size = New System.Drawing.Size(612, 216)
        Me.DataGrid1.TabIndex = 0
        '
        'DataGrid2
        '
        Me.DataGrid2.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.DataGrid2.DataMember = ""
        Me.DataGrid2.HeaderForeColor = System.Drawing.SystemColors.ControlText
        Me.DataGrid2.Location = New System.Drawing.Point(16, 256)
        Me.DataGrid2.Name = "DataGrid2"
        Me.DataGrid2.Size = New System.Drawing.Size(612, 216)
        Me.DataGrid2.TabIndex = 1
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(640, 486)
        Me.Controls.Add(Me.DataGrid2)
        Me.Controls.Add(Me.DataGrid1)
        Me.MaximizeBox = False
        Me.MinimizeBox = False
        Me.Name = "Form1"
        Me.Text = "Form1"
        CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.DataGrid2, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

    End Sub

#End Region

    Dim ds As New DataSet

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim strConn As String
        Dim strSQL As String
        Dim da, daEmployees As OleDbDataAdapter
        Dim conn As OleDbConnection

        strConn = "Provider = Microsoft.Jet.OLEDB.4.0;"
        strConn &= "Data Source = Northwind.mdb;"

        conn = New OleDbConnection(strConn)
        da = New OleDbDataAdapter("Select * From Categories", conn)
        da.Fill(ds, "Categories")

        daEmployees = New OleDbDataAdapter("Select * From Employees Order by LastName, FirstName", conn)
        daEmployees.Fill(ds, "Employees")

        SetupGrid()
        SetupEmployees()

        DataGrid1.DataSource = ds.Tables("Categories")
        DataGrid2.DataSource = ds.Tables("Employees")
        AddHandler ds.Tables("Employees").DefaultView.ListChanged, AddressOf ListChanged
    End Sub

    Private Sub SetupGrid()
        Dim ts As New DataGridTableStyle
        ts.MappingName = "Categories"

        ts.SelectionBackColor = Color.Yellow
        ts.SelectionForeColor = Color.Red

        Dim colPic As New DataGridImageColumn
        With colPic
            .MappingName = "Picture"
            .HeaderText = "Image"
            .Width = 100
        End With

        Dim colName As New ColoredGridColumn
        With colName
            .MappingName = "CategoryName"
            .HeaderText = "Name"
            .Width = 100
            .ForeColor = Color.Blue
            .BackColor = Color.SkyBlue
        End With

        Dim colDescription As New ColoredGridColumn
        With colDescription
            .MappingName = "Description"
            .HeaderText = "Description"
            .Width = 350
            .ForeColor = Color.Blue
            .BackColor = Color.SkyBlue
        End With


        ts.GridColumnStyles.Add(colPic)
        ts.GridColumnStyles.Add(colName)
        ts.GridColumnStyles.Add(colDescription)

        DataGrid1.TableStyles.Add(ts)
        ts = Nothing
        colDescription = Nothing
        colName = Nothing
    End Sub

    Private Sub SetupEmployees()
        Dim ts As New DataGridTableStyle
        ts.MappingName = "Employees"

        ts.SelectionBackColor = Color.Yellow
        ts.SelectionForeColor = Color.Red

        Dim colPic As New DataGridImageColumn
        With colPic
            .MappingName = "Photo"
            .HeaderText = "Image"
            .Width = 100
        End With

        Dim colName As New DataGridTextBoxColumn
        With colName
            .MappingName = "LastName"
            .HeaderText = "Name"
            .Width = 100
        End With

        Dim colDescription As New MultiLineColumn
        With colDescription
            .MappingName = "Notes"
            .HeaderText = "Notes"
            .Width = 350
        End With


        ts.GridColumnStyles.Add(colPic)
        ts.GridColumnStyles.Add(colName)
        ts.GridColumnStyles.Add(colDescription)

        DataGrid2.TableStyles.Add(ts)
        ts = Nothing
        colDescription = Nothing
        colName = Nothing
    End Sub


    Private Sub ListChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ListChangedEventArgs)
        Dim hti As DataGrid.HitTestInfo
        Dim pt As Point

        pt = DataGrid2.PointToClient(Me.MousePosition)

        hti = DataGrid2.HitTest(pt)

        Trace.WriteLine(String.Format("Sort on column {0}", hti.Column))

    End Sub
End Class
===============================================
Class  ColoredGridColumn.vb
=====================
Imports System.Drawing.Drawing2D

Public Class ColoredGridColumn
    Inherits DataGridTextBoxColumn

    Dim mForeColor As Color = Color.Black
    Dim mBackColor As Color = Color.White


    Public Property ForeColor() As Color
        Get
            Return mForeColor
        End Get
        Set(ByVal Value As Color)
            mForeColor = Value
        End Set
    End Property

    Public Property BackColor() As Color
        Get
            Return mBackColor
        End Get
        Set(ByVal Value As Color)
            mBackColor = Value
        End Set
    End Property

    Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal backBrush As System.Drawing.Brush, ByVal foreBrush As System.Drawing.Brush, ByVal alignToRight As Boolean)
        Dim brFore As Brush
        Dim brBack As Brush
        Dim cFore As Color
        Dim cBack As Color

        If Me.DataGridTableStyle.DataGrid.IsSelected(rowNum) Then
            cFore = Me.DataGridTableStyle.SelectionForeColor
            cBack = Me.DataGridTableStyle.SelectionBackColor
        Else
            cFore = ForeColor
            cBack = BackColor
        End If

        brBack = New LinearGradientBrush(bounds, cBack, Color.White, 90, False)
        brFore = New SolidBrush(cFore)

        Dim bl As New Blend

        bl.Factors = New Single() {0.0F, 0.1F, 0.5F, 0.7F, 0.7F, 0.5F, 0.3F, 0.2F, 0}

        bl.Positions = New Single() {0, 0.1F, 0.2F, 0.5F, 0.6F, 0.7F, 0.8F, 0.9F, 1.0F}

        DirectCast(brBack, LinearGradientBrush).Blend = bl

        MyBase.Paint(g, bounds, source, rowNum, brBack, brFore, alignToRight)

    End Sub



    Protected Overloads Overrides Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, ByVal instantText As String, ByVal cellIsVisible As Boolean)
        MyBase.Edit(source, rowNum, bounds, [readOnly], instantText, cellIsVisible)
        MyBase.TextBox.ForeColor = ForeColor
        MyBase.TextBox.BackColor = BackColor
    End Sub
End Class
===============================================
Class DataGridImageColumn.vb
========================
Imports System.Reflection
Imports System.IO

Public Class DataGridImageColumn
    Inherits DataGridTextBoxColumn

    Dim WithEvents dg As DataGrid
    Private arHeights As ArrayList
    Private mintOffset As Integer
    Private cm As CurrencyManager

    Public Sub New()
        Me.NullText = "Image not available."
    End Sub

    Private Sub GetHeightList()
        Dim mi As MethodInfo = dg.GetType().GetMethod("get_DataGridRows", BindingFlags.FlattenHierarchy Or BindingFlags.IgnoreCase Or BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.Public Or BindingFlags.Static)

        Dim dgra As Array = CType(mi.Invoke(Me.dg, Nothing), Array)

        arHeights = New ArrayList
        Dim dgRowHeight As Object
        For Each dgRowHeight In dgra
            If dgRowHeight.ToString().EndsWith("DataGridRelationshipRow") = True Then
                arHeights.Add(dgRowHeight)
            End If
        Next
    End Sub



    Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal backBrush As System.Drawing.Brush, ByVal foreBrush As System.Drawing.Brush, ByVal alignToRight As Boolean)
        Static bPainted As Boolean = False
        Static bMove As Boolean = True

        If Not bPainted Then
            dg = Me.DataGridTableStyle.DataGrid
            cm = source
            GetHeightList()
        End If

        If source.Count - 1 = rowNum And bMove Then
            '
            ' Force resize so scroll bars show
            '
            dg.Size = New Size(dg.Size.Width, dg.Height - 1)
            bMove = False
            dg.Size = New Size(dg.Size.Width, dg.Height + 1)
        End If

        'clear the cell
        g.FillRectangle(backBrush, bounds)

        Dim objData As Object = Me.GetColumnValueAtRow([source], rowNum)
        If TypeOf objData Is System.DBNull Then
            Dim sf As New StringFormat

            With sf
                .Alignment = StringAlignment.Center
                .LineAlignment = StringAlignment.Center
            End With

            g.DrawString(Me.NullText, Me.TextBox.Font, Brushes.Black, _
                   RectangleF.op_Implicit(bounds), sf)
        Else
            Try
                Dim bm As Bitmap

                If TypeOf objData Is String Then
                    Dim fs As New FileStream(objData.ToString, FileMode.Open)
                    bm = CType(Bitmap.FromStream(fs), Bitmap)
                    fs.Close()
                Else
                    Try
                        bm = ConvertToBitmap(DirectCast(objData, Byte()), 78)
                    Catch
                        bm = ConvertToBitmap(DirectCast(objData, Byte()), 0)
                    End Try
                End If
                Dim h As Integer
                Dim s As Double

                s = (Me.Width / bm.Width)
                h = CInt(bm.Height * s)

                If s >= 1 Then
                    h = bm.Height
                End If

                AdjustHeight(h)

                Dim r As Rectangle

                If Me.Width > bm.Width Then
                    r = New Rectangle(bounds.Left, bounds.Top, bm.Width, bm.Height)
                Else
                    r = New Rectangle(bounds.Left, bounds.Top, Me.Width, h)
                End If

                g.DrawImage(bm, r)
                If dg.IsSelected(rowNum) Then
                    Dim br As New SolidBrush(Color.FromArgb(64, _
                        Me.DataGridTableStyle.SelectionBackColor))
                    g.FillRectangle(br, bounds)
                    br.Dispose()
                End If
            Catch ex As Exception
                Dim sf As New StringFormat

                With sf
                    .Alignment = StringAlignment.Center
                    .LineAlignment = StringAlignment.Center
                End With

                g.DrawString("Invalid image format", Me.TextBox.Font, Brushes.Black, _
                    RectangleF.op_Implicit(bounds), sf)
            End Try
        End If
        bPainted = True
    End Sub

    Protected Overloads Overrides Sub Edit(ByVal source As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, ByVal instantText As String, ByVal cellIsVisible As Boolean)

    End Sub

    Private Sub AdjustHeight(ByVal h As Integer)
        Dim curHeight As Integer = Me.DataGridTableStyle.PreferredRowHeight

        If h > curHeight Then
            '
            ' Manually set all the row heights to the new height
            '

            Me.DataGridTableStyle.PreferredRowHeight = h
            Trace.WriteLine(h)

            If arHeights.Count < cm.Count Then
                GetHeightList()
            End If

            For rownum As Integer = 0 To cm.Count - 1
                Try
                    Dim pi As PropertyInfo
                    pi = arHeights(rownum).GetType().GetProperty("Height")

                    ' adjust height

                    If h > curHeight Then
                        pi.SetValue(arHeights(rownum), h, Nothing)
                    End If

                Catch
                    ' something wrong leave default height
                    Debug.WriteLine("Error")
                End Try
            Next

            '
            ' Resize datagrid to get scrollbars to work right
            '

            Dim sz As Size = dg.Size
            dg.Size = New Size(New Point(sz.Width - 1, sz.Height - 1))
            dg.Size = sz
        End If

    End Sub



    Private Function ConvertToBitmap(ByVal data() As Byte, ByVal offset As Integer) As Bitmap
        Dim ms As New System.IO.MemoryStream
        Dim bm As Bitmap

        ms = New MemoryStream
        ms.Write(data, offset, data.Length - offset)

        bm = New Bitmap(ms)
        Return bm
    End Function
End Class
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Loops Section Overview
Suggested Courses
Course of the Month15 days, 22 hours left to enroll

850 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