Hi,
You should create a datagrid column style to do that. Here is an
example of an image column that shows how to tell when the column is
selected. You will have to draw your circle in the paint event. Keep in
mind that you have to draw part of the circle in each column shown.
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms
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("DataGridRelations hipRow") = 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
<DataSysDescription("Suspends painting of column until EndUpdate is
called")> _
Public Shadows Sub BeginUpdate()
MyBase.BeginUpdate()
End Sub
<DataSysDescription("Resumes painting of column")> _
Public Shadows Sub EndUpdate()
MyBase.EndUpdate()
End Sub
End Class
Ken
---------------------
"Richard" <a@b.com> wrote in message
news:vg********************@twister.nyc.rr.com...
I have a requirement to put a GDI style circle or rectangle border around
the selected row of a datagrid/ It will overlap into the row above and below
the selected row. Doing this in a the OnPaint of a subclassed
DataGridTextBoxColum dos not seem like a practical way to do it.
I have subclassed a DataGrid and overridden the OnPaint as such:
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
// Create pen.
Pen blackPen = new Pen(Color.Green, 2);
// Create location and size of rectangle.
float x = 15.0F;
float y = 53.0F;
float width = 500.0F;
float height = 20.0F;
// Draw rectangle to screen.
pe.Graphics.DrawRectangle(blackPen, x, y, width, height);
}
It works but has refresh problems.
Last week Bob Powell [MVP] suggested that I use a NativeWindow class to
solve this problem. I've just had the time to get back to this and not being
a former C++ person, etc., etc., etc. maybe someone can help with this.
The MSDN help screen for the NativeWindow class is this link:
http://msdn.microsoft.com/library/de...classtopic.asp
It has an example and in the subclassed NativeWindow constructor it creates
a button:
public MyNativeWindow(Form parent)
{
...see help example
}
Can someone advise me on where my code above that paints the Rectangle
should go in this NativeWindow example?