By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,143 Members | 1,854 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,143 IT Pros & Developers. It's quick & easy.

Datagrid Overrides Question

P: n/a
Hi Folks,

I'm adding some columns to my datagrid which are of Combo Box type. I'm
inheriting DataGridTextBoxColumn and doing all the usual stuff to get them
populated. This is working fine. I have added some functionality where if
the user right clicks the combobox a context menu will appear, saying "Fill
the complete column with value 'XXX'". This value is the value they selected
from the combobox. This is also working fine.

However, to get this working generically for any datagrid, I'm running into
problems. I overload the constructor to pass in the datagrid (by ref) and
datatable, but I need to know the column the user clicked which I'm not
really sure how to do this.

I had this working before for one particular datagrid in my app. I passed in
a reference to the class containing the datagrid when the columns were
created but I'm trying to make it generic now so any datagrid can uses this
context menu function.

The reason I need to know the column selected is when I loop thru all the
rows and columns I know which cell to update.

I'm still fairly green with vb.net (win), ...do I need to get an event to
fire off, ..or add a addhandler to the constructor? The problem is I can't
do the HitTest for the datagrid within the "DataGridComboBoxColumn" class.

Again : I need to know the column the user clicked on the datagrid.

Hope I've explained this well enough. Any help would really be appreciated,
cause this one has got me for days.

Thanks,
Anthony
Nov 21 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Hi,

Sure you can use hit test info for a data grid in the column style.
Here is a sample column that i wrote that high lights the column the mouse
is under. I hope this helps.
Public Class HotTrackTextBoxColumn

Inherits DataGridTextBoxColumn

Dim c As Integer

Dim rectPaint As New RectangleF

Dim fnt As New Font(MyBase.TextBox.Font.Name, MyBase.TextBox.Font.Size,
FontStyle.Underline)

Dim WithEvents dg As DataGrid

Dim oldCell As New Point(-1, -1)

Dim isInCell As Boolean = False

Public Sub HandleMouseMove(ByVal sender As Object, ByVal e As
MouseEventArgs) Handles dg.MouseMove

Dim g As Graphics = dg.CreateGraphics

Dim bounds As Rectangle

Dim hti As DataGrid.HitTestInfo = dg.HitTest(New Point(e.X, e.Y))

isInCell = (hti.Row > -1 And hti.Column = c)

Static bRedraw As Boolean = False

If isInCell Then

Dim pt As Point

pt = New Point(hti.Row, hti.Column)

If Not pt.Equals(oldCell) Then

'

' Create a region where we want the datagrid to redraw

' So the datagrid doesn't flash.

'

Dim pthToRedraw As New Drawing2D.GraphicsPath

Dim rgnToRedraw As Region

Dim rCell As Rectangle = dg.GetCellBounds(pt.X, pt.Y)

pthToRedraw.AddRectangle(rCell)

If oldCell.X > -1 Then

'

' Have to redraw last cell

'

pthToRedraw.AddRectangle(dg.GetCellBounds(oldCell. X, oldCell.Y))

End If

rgnToRedraw = New Region(pthToRedraw)

dg.Invalidate(rgnToRedraw)

End If

'

' Flag datagrid for redraw

'

bRedraw = True

oldCell = pt

Else

'

' Only redraw when needed

'

If bRedraw Then

dg.Invalidate(dg.GetCellBounds(oldCell.X, oldCell.Y))

End If

bRedraw = False

oldCell = New Point(-1, -1)

End If

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

'

' First time we paint get a reference to datagrid

' So we can consume its events

'

If Not bPainted Then

dg = Me.DataGridTableStyle.DataGrid

c = -1

For Each grdCol As DataGridColumnStyle In
Me.DataGridTableStyle.GridColumnStyles

c += 1

If grdCol.MappingName = Me.MappingName Then Exit For

Next

End If

Dim pt As New Point(rowNum, c)

bPainted = True

MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight)

Dim brHot As New SolidBrush(Color.FromArgb(128, SystemColors.HotTrack))

If MouseOverCell(rowNum) Then

bounds.Inflate(-1, -1)

g.FillRectangle(brHot, bounds)

g.DrawRectangle(Pens.Blue, bounds)

End If

Dim r As New RectangleF(bounds.X, bounds.Y, bounds.Width, bounds.Height)

rectPaint = r

End Sub

Public ReadOnly Property MouseOverCell(ByVal rownum As Integer) As Boolean

Get

Dim pt As New Point(rownum, c)

Trace.WriteLine(String.Format("{0} {1}", oldCell.ToString, pt.ToString))

Return pt.Equals(oldCell)

End Get

End Property

End Class

Ken

-------------------------

"Anthony" <an*****@sysdel.com.au> wrote in message
news:eR**************@TK2MSFTNGP12.phx.gbl...
Hi Folks,

I'm adding some columns to my datagrid which are of Combo Box type. I'm
inheriting DataGridTextBoxColumn and doing all the usual stuff to get them
populated. This is working fine. I have added some functionality where if
the user right clicks the combobox a context menu will appear, saying "Fill
the complete column with value 'XXX'". This value is the value they selected
from the combobox. This is also working fine.

However, to get this working generically for any datagrid, I'm running into
problems. I overload the constructor to pass in the datagrid (by ref) and
datatable, but I need to know the column the user clicked which I'm not
really sure how to do this.

I had this working before for one particular datagrid in my app. I passed in
a reference to the class containing the datagrid when the columns were
created but I'm trying to make it generic now so any datagrid can uses this
context menu function.

The reason I need to know the column selected is when I loop thru all the
rows and columns I know which cell to update.

I'm still fairly green with vb.net (win), ...do I need to get an event to
fire off, ..or add a addhandler to the constructor? The problem is I can't
do the HitTest for the datagrid within the "DataGridComboBoxColumn" class.

Again : I need to know the column the user clicked on the datagrid.

Hope I've explained this well enough. Any help would really be appreciated,
cause this one has got me for days.

Thanks,
Anthony

Nov 21 '05 #2

P: n/a
Hi,

Sure you can use hit test info for a data grid in the column style.
Here is a sample column that i wrote that high lights the column the mouse
is under. I hope this helps.
Public Class HotTrackTextBoxColumn

Inherits DataGridTextBoxColumn

Dim c As Integer

Dim rectPaint As New RectangleF

Dim fnt As New Font(MyBase.TextBox.Font.Name, MyBase.TextBox.Font.Size,
FontStyle.Underline)

Dim WithEvents dg As DataGrid

Dim oldCell As New Point(-1, -1)

Dim isInCell As Boolean = False

Public Sub HandleMouseMove(ByVal sender As Object, ByVal e As
MouseEventArgs) Handles dg.MouseMove

Dim g As Graphics = dg.CreateGraphics

Dim bounds As Rectangle

Dim hti As DataGrid.HitTestInfo = dg.HitTest(New Point(e.X, e.Y))

isInCell = (hti.Row > -1 And hti.Column = c)

Static bRedraw As Boolean = False

If isInCell Then

Dim pt As Point

pt = New Point(hti.Row, hti.Column)

If Not pt.Equals(oldCell) Then

'

' Create a region where we want the datagrid to redraw

' So the datagrid doesn't flash.

'

Dim pthToRedraw As New Drawing2D.GraphicsPath

Dim rgnToRedraw As Region

Dim rCell As Rectangle = dg.GetCellBounds(pt.X, pt.Y)

pthToRedraw.AddRectangle(rCell)

If oldCell.X > -1 Then

'

' Have to redraw last cell

'

pthToRedraw.AddRectangle(dg.GetCellBounds(oldCell. X, oldCell.Y))

End If

rgnToRedraw = New Region(pthToRedraw)

dg.Invalidate(rgnToRedraw)

End If

'

' Flag datagrid for redraw

'

bRedraw = True

oldCell = pt

Else

'

' Only redraw when needed

'

If bRedraw Then

dg.Invalidate(dg.GetCellBounds(oldCell.X, oldCell.Y))

End If

bRedraw = False

oldCell = New Point(-1, -1)

End If

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

'

' First time we paint get a reference to datagrid

' So we can consume its events

'

If Not bPainted Then

dg = Me.DataGridTableStyle.DataGrid

c = -1

For Each grdCol As DataGridColumnStyle In
Me.DataGridTableStyle.GridColumnStyles

c += 1

If grdCol.MappingName = Me.MappingName Then Exit For

Next

End If

Dim pt As New Point(rowNum, c)

bPainted = True

MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight)

Dim brHot As New SolidBrush(Color.FromArgb(128, SystemColors.HotTrack))

If MouseOverCell(rowNum) Then

bounds.Inflate(-1, -1)

g.FillRectangle(brHot, bounds)

g.DrawRectangle(Pens.Blue, bounds)

End If

Dim r As New RectangleF(bounds.X, bounds.Y, bounds.Width, bounds.Height)

rectPaint = r

End Sub

Public ReadOnly Property MouseOverCell(ByVal rownum As Integer) As Boolean

Get

Dim pt As New Point(rownum, c)

Trace.WriteLine(String.Format("{0} {1}", oldCell.ToString, pt.ToString))

Return pt.Equals(oldCell)

End Get

End Property

End Class

Ken

-------------------------

"Anthony" <an*****@sysdel.com.au> wrote in message
news:eR**************@TK2MSFTNGP12.phx.gbl...
Hi Folks,

I'm adding some columns to my datagrid which are of Combo Box type. I'm
inheriting DataGridTextBoxColumn and doing all the usual stuff to get them
populated. This is working fine. I have added some functionality where if
the user right clicks the combobox a context menu will appear, saying "Fill
the complete column with value 'XXX'". This value is the value they selected
from the combobox. This is also working fine.

However, to get this working generically for any datagrid, I'm running into
problems. I overload the constructor to pass in the datagrid (by ref) and
datatable, but I need to know the column the user clicked which I'm not
really sure how to do this.

I had this working before for one particular datagrid in my app. I passed in
a reference to the class containing the datagrid when the columns were
created but I'm trying to make it generic now so any datagrid can uses this
context menu function.

The reason I need to know the column selected is when I loop thru all the
rows and columns I know which cell to update.

I'm still fairly green with vb.net (win), ...do I need to get an event to
fire off, ..or add a addhandler to the constructor? The problem is I can't
do the HitTest for the datagrid within the "DataGridComboBoxColumn" class.

Again : I need to know the column the user clicked on the datagrid.

Hope I've explained this well enough. Any help would really be appreciated,
cause this one has got me for days.

Thanks,
Anthony

Nov 21 '05 #3

P: n/a
Thanks for your solution Ken, but I've just figured it out.

Would you believe, ...
m_DataGrid.CurrentCell.ColumnNumber

That's it, ...I can call this in my DataGridComboBoxColumn class (Inherits
DataGridTextBoxColumn) and Bobs your mothers brother.

I will have a look at you solution too, ...(looks quite hard core)


"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:Ok**************@tk2msftngp13.phx.gbl...
Hi,

Sure you can use hit test info for a data grid in the column style. Here is a sample column that i wrote that high lights the column the mouse
is under. I hope this helps.
Public Class HotTrackTextBoxColumn

Inherits DataGridTextBoxColumn

Dim c As Integer

Dim rectPaint As New RectangleF

Dim fnt As New Font(MyBase.TextBox.Font.Name, MyBase.TextBox.Font.Size,
FontStyle.Underline)

Dim WithEvents dg As DataGrid

Dim oldCell As New Point(-1, -1)

Dim isInCell As Boolean = False

Public Sub HandleMouseMove(ByVal sender As Object, ByVal e As
MouseEventArgs) Handles dg.MouseMove

Dim g As Graphics = dg.CreateGraphics

Dim bounds As Rectangle

Dim hti As DataGrid.HitTestInfo = dg.HitTest(New Point(e.X, e.Y))

isInCell = (hti.Row > -1 And hti.Column = c)

Static bRedraw As Boolean = False

If isInCell Then

Dim pt As Point

pt = New Point(hti.Row, hti.Column)

If Not pt.Equals(oldCell) Then

'

' Create a region where we want the datagrid to redraw

' So the datagrid doesn't flash.

'

Dim pthToRedraw As New Drawing2D.GraphicsPath

Dim rgnToRedraw As Region

Dim rCell As Rectangle = dg.GetCellBounds(pt.X, pt.Y)

pthToRedraw.AddRectangle(rCell)

If oldCell.X > -1 Then

'

' Have to redraw last cell

'

pthToRedraw.AddRectangle(dg.GetCellBounds(oldCell. X, oldCell.Y))

End If

rgnToRedraw = New Region(pthToRedraw)

dg.Invalidate(rgnToRedraw)

End If

'

' Flag datagrid for redraw

'

bRedraw = True

oldCell = pt

Else

'

' Only redraw when needed

'

If bRedraw Then

dg.Invalidate(dg.GetCellBounds(oldCell.X, oldCell.Y))

End If

bRedraw = False

oldCell = New Point(-1, -1)

End If

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

'

' First time we paint get a reference to datagrid

' So we can consume its events

'

If Not bPainted Then

dg = Me.DataGridTableStyle.DataGrid

c = -1

For Each grdCol As DataGridColumnStyle In
Me.DataGridTableStyle.GridColumnStyles

c += 1

If grdCol.MappingName = Me.MappingName Then Exit For

Next

End If

Dim pt As New Point(rowNum, c)

bPainted = True

MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight)
Dim brHot As New SolidBrush(Color.FromArgb(128, SystemColors.HotTrack))

If MouseOverCell(rowNum) Then

bounds.Inflate(-1, -1)

g.FillRectangle(brHot, bounds)

g.DrawRectangle(Pens.Blue, bounds)

End If

Dim r As New RectangleF(bounds.X, bounds.Y, bounds.Width, bounds.Height)

rectPaint = r

End Sub

Public ReadOnly Property MouseOverCell(ByVal rownum As Integer) As Boolean

Get

Dim pt As New Point(rownum, c)

Trace.WriteLine(String.Format("{0} {1}", oldCell.ToString, pt.ToString))

Return pt.Equals(oldCell)

End Get

End Property

End Class

Ken

-------------------------

"Anthony" <an*****@sysdel.com.au> wrote in message
news:eR**************@TK2MSFTNGP12.phx.gbl...
Hi Folks,

I'm adding some columns to my datagrid which are of Combo Box type. I'm
inheriting DataGridTextBoxColumn and doing all the usual stuff to get them
populated. This is working fine. I have added some functionality where if
the user right clicks the combobox a context menu will appear, saying "Fill the complete column with value 'XXX'". This value is the value they selected from the combobox. This is also working fine.

However, to get this working generically for any datagrid, I'm running into problems. I overload the constructor to pass in the datagrid (by ref) and
datatable, but I need to know the column the user clicked which I'm not
really sure how to do this.

I had this working before for one particular datagrid in my app. I passed in a reference to the class containing the datagrid when the columns were
created but I'm trying to make it generic now so any datagrid can uses this context menu function.

The reason I need to know the column selected is when I loop thru all the
rows and columns I know which cell to update.

I'm still fairly green with vb.net (win), ...do I need to get an event to
fire off, ..or add a addhandler to the constructor? The problem is I can't
do the HitTest for the datagrid within the "DataGridComboBoxColumn" class.

Again : I need to know the column the user clicked on the datagrid.

Hope I've explained this well enough. Any help would really be appreciated, cause this one has got me for days.

Thanks,
Anthony

Nov 21 '05 #4

P: n/a
Thanks for your solution Ken, but I've just figured it out.

Would you believe, ...
m_DataGrid.CurrentCell.ColumnNumber

That's it, ...I can call this in my DataGridComboBoxColumn class (Inherits
DataGridTextBoxColumn) and Bobs your mothers brother.

I will have a look at you solution too, ...(looks quite hard core)


"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:Ok**************@tk2msftngp13.phx.gbl...
Hi,

Sure you can use hit test info for a data grid in the column style. Here is a sample column that i wrote that high lights the column the mouse
is under. I hope this helps.
Public Class HotTrackTextBoxColumn

Inherits DataGridTextBoxColumn

Dim c As Integer

Dim rectPaint As New RectangleF

Dim fnt As New Font(MyBase.TextBox.Font.Name, MyBase.TextBox.Font.Size,
FontStyle.Underline)

Dim WithEvents dg As DataGrid

Dim oldCell As New Point(-1, -1)

Dim isInCell As Boolean = False

Public Sub HandleMouseMove(ByVal sender As Object, ByVal e As
MouseEventArgs) Handles dg.MouseMove

Dim g As Graphics = dg.CreateGraphics

Dim bounds As Rectangle

Dim hti As DataGrid.HitTestInfo = dg.HitTest(New Point(e.X, e.Y))

isInCell = (hti.Row > -1 And hti.Column = c)

Static bRedraw As Boolean = False

If isInCell Then

Dim pt As Point

pt = New Point(hti.Row, hti.Column)

If Not pt.Equals(oldCell) Then

'

' Create a region where we want the datagrid to redraw

' So the datagrid doesn't flash.

'

Dim pthToRedraw As New Drawing2D.GraphicsPath

Dim rgnToRedraw As Region

Dim rCell As Rectangle = dg.GetCellBounds(pt.X, pt.Y)

pthToRedraw.AddRectangle(rCell)

If oldCell.X > -1 Then

'

' Have to redraw last cell

'

pthToRedraw.AddRectangle(dg.GetCellBounds(oldCell. X, oldCell.Y))

End If

rgnToRedraw = New Region(pthToRedraw)

dg.Invalidate(rgnToRedraw)

End If

'

' Flag datagrid for redraw

'

bRedraw = True

oldCell = pt

Else

'

' Only redraw when needed

'

If bRedraw Then

dg.Invalidate(dg.GetCellBounds(oldCell.X, oldCell.Y))

End If

bRedraw = False

oldCell = New Point(-1, -1)

End If

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

'

' First time we paint get a reference to datagrid

' So we can consume its events

'

If Not bPainted Then

dg = Me.DataGridTableStyle.DataGrid

c = -1

For Each grdCol As DataGridColumnStyle In
Me.DataGridTableStyle.GridColumnStyles

c += 1

If grdCol.MappingName = Me.MappingName Then Exit For

Next

End If

Dim pt As New Point(rowNum, c)

bPainted = True

MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight)
Dim brHot As New SolidBrush(Color.FromArgb(128, SystemColors.HotTrack))

If MouseOverCell(rowNum) Then

bounds.Inflate(-1, -1)

g.FillRectangle(brHot, bounds)

g.DrawRectangle(Pens.Blue, bounds)

End If

Dim r As New RectangleF(bounds.X, bounds.Y, bounds.Width, bounds.Height)

rectPaint = r

End Sub

Public ReadOnly Property MouseOverCell(ByVal rownum As Integer) As Boolean

Get

Dim pt As New Point(rownum, c)

Trace.WriteLine(String.Format("{0} {1}", oldCell.ToString, pt.ToString))

Return pt.Equals(oldCell)

End Get

End Property

End Class

Ken

-------------------------

"Anthony" <an*****@sysdel.com.au> wrote in message
news:eR**************@TK2MSFTNGP12.phx.gbl...
Hi Folks,

I'm adding some columns to my datagrid which are of Combo Box type. I'm
inheriting DataGridTextBoxColumn and doing all the usual stuff to get them
populated. This is working fine. I have added some functionality where if
the user right clicks the combobox a context menu will appear, saying "Fill the complete column with value 'XXX'". This value is the value they selected from the combobox. This is also working fine.

However, to get this working generically for any datagrid, I'm running into problems. I overload the constructor to pass in the datagrid (by ref) and
datatable, but I need to know the column the user clicked which I'm not
really sure how to do this.

I had this working before for one particular datagrid in my app. I passed in a reference to the class containing the datagrid when the columns were
created but I'm trying to make it generic now so any datagrid can uses this context menu function.

The reason I need to know the column selected is when I loop thru all the
rows and columns I know which cell to update.

I'm still fairly green with vb.net (win), ...do I need to get an event to
fire off, ..or add a addhandler to the constructor? The problem is I can't
do the HitTest for the datagrid within the "DataGridComboBoxColumn" class.

Again : I need to know the column the user clicked on the datagrid.

Hope I've explained this well enough. Any help would really be appreciated, cause this one has got me for days.

Thanks,
Anthony

Nov 21 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.