Here is the code for my basic ExtendedDataGridColumn as well as for an
inherited ExtendedComboBoxColumn.
#Region "ExtendedDataGridColumn"
Public MustInherit Class ExtendedDataGridColumnStyle
Inherits DataGridColumnStyle
#Region "Private"
#Region "Properties"
Private mxMargin As Integer = 2
Private myMargin As Integer = 1
Private WithEvents mcellControl As Control = Nothing
Private mText As String = ""
Private moldVal As String = String.Empty
Private minEdit As Boolean = False
Private mrowNum As Integer
Private WithEvents msource As CurrencyManager
Private mIsDirty As Boolean = False
Private ReadOnly Property DataGridTableGridLineWidth() As Integer
Get
If Me.DataGridTableStyle.GridLineStyle =
DataGridLineStyle.Solid Then
Return 1
Else
Return 0
End If
End Get
End Property
#End Region
#End Region
#Region "Protected"
#Region "Functions"
Protected Overrides Function GetPreferredHeight(ByVal g As
System.Drawing.Graphics, ByVal value As Object) As Integer
Dim NewLineIndex As Integer = 0
Dim NewLines As Integer = 0
Dim ValueString As String = Me.GetText(value)
Do
While NewLineIndex <> -1
NewLineIndex = ValueString.IndexOf("r\n",
NewLineIndex + 1)
NewLines += 1
End While
Loop
Return FontHeight * NewLines + myMargin
End Function
Protected Overrides Function GetPreferredSize(ByVal g As
System.Drawing.Graphics, ByVal value As Object) As System.Drawing.Size
Dim Extents As Size =
Size.Ceiling(g.MeasureString(GetText(value), _
Me.DataGridTableStyle.DataGrid.Font))
Extents.Width += mxMargin * 2 + DataGridTableGridLineWidth
Extents.Height += myMargin
Return Extents
End Function
Protected Overridable Function GetText(ByVal Value As Object) As
String
If Value Is System.DBNull.Value Then Return NullText
If Not Value Is Nothing Then
Return Value.ToString
Else
Return String.Empty
End If
End Function
Protected Overrides Sub ColumnStartedEditing(ByVal
editingControl As System.Windows.Forms.Control)
RaiseEvent ColumnEdited(Me, New System.EventArgs)
If (Not editingControl.Text = Me.OldValue) _
OrElse (editingControl.Text Is Nothing And Not Me.OldValue
Is Nothing) _
OrElse (Not editingControl.Text Is Nothing And Me.OldValue
Is Nothing) Then
RaiseEvent ColumnDirty(Me, New System.EventArgs)
End If
MyBase.ColumnStartedEditing(editingControl)
End Sub
Protected MustOverride Function GetColumnTextAtRow(ByVal Source
As CurrencyManager, _
ByVal RowNum
As Integer) As Object
#End Region
#Region "Properties"
Protected Property CellControl() As Control
Get
Return mcellControl
End Get
Set(ByVal Value As Control)
mcellControl = Value
End Set
End Property
Protected Property RowNumber() As Integer
Get
Return mrowNum
End Get
Set(ByVal Value As Integer)
mrowNum = Value
End Set
End Property
Protected Property GridDataSource() As CurrencyManager
Get
Return msource
End Get
Set(ByVal Value As CurrencyManager)
msource = Value
End Set
End Property
Protected Property InEdit() As Boolean
Get
Return minEdit
End Get
Set(ByVal Value As Boolean)
minEdit = Value
End Set
End Property
Protected ReadOnly Property yMargin() As Integer
Get
Return myMargin
End Get
End Property
Protected ReadOnly Property xMargin() As Integer
Get
Return mxMargin
End Get
End Property
Protected Property OldValue() As Object
Get
Return moldVal
End Get
Set(ByVal Value As Object)
If Not Value Is System.DBNull.Value Then
moldVal = Value
Else
moldVal = String.Empty
End If
End Set
End Property
Protected Property IsDirty() As Boolean
Get
Return mIsDirty
End Get
Set(ByVal Value As Boolean)
If Not mIsDirty = False Then
mIsDirty = Value
RaiseEvent ColumnDirty(Me, New System.EventArgs)
End If
End Set
End Property
#End Region
#Region "Subroutines"
Protected Overrides Sub Abort(ByVal rowNum As Integer)
RollBack()
EndEdit()
Invalidate()
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)
Paint(g, bounds, source, rowNum, False)
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 alignToRight As
Boolean)
Dim Text As String = GetText(GetColumnTextAtRow(source,
rowNum))
'Dim BackBrush As Brush
'Dim ForeBrush As Brush
'If Me.DataGridTableStyle.DataGrid.IsSelected(rowNum) Then
' BackBrush = New
SolidBrush(Me.DataGridTableStyle.SelectionBackColo r)
' ForeBrush = New
SolidBrush(Me.DataGridTableStyle.ForeColor)
'Else
' BackBrush = New
SolidBrush(Me.DataGridTableStyle.BackColor)
' ForeBrush = New
SolidBrush(Me.DataGridTableStyle.ForeColor)
'End If
PaintText(g, bounds, Text, alignToRight)
'PaintText(g, bounds, Text, BackBrush, ForeBrush,
alignToRight)
End Sub
Protected Overloads Sub Paint(ByVal g As Graphics, _
ByVal Bounds As Rectangle, _
ByVal Source As CurrencyManager, _
ByVal RowNum As Integer, _
ByVal BackBrush As Brush, _
ByVal ForeBrush As Brush, _
ByVal AlignToRight As Boolean)
Dim Text As String = GetText(GetColumnTextAtRow(Source,
RowNum))
PaintText(g, Bounds, Text, BackBrush, ForeBrush, AlignToRight)
End Sub
Protected Overloads Overrides Sub SetDataGridInColumn(ByVal
Value As DataGrid)
MyBase.SetDataGridInColumn(Value)
If Not (mcellControl.Parent Is Value) Then
If Not (mcellControl.Parent Is Nothing) Then
mcellControl.Parent.Controls.Remove(mcellControl)
End If
End If
If Not (Value Is Nothing) Then
Value.Controls.Add(mcellControl)
End Sub
Protected Overloads Overrides Sub UpdateUI(ByVal Source As
CurrencyManager, _
ByVal RowNum As
Integer, ByVal InstantText As String)
mcellControl.Text = GetText(GetColumnTextAtRow(Source,
RowNum))
If Not (InstantText Is Nothing) Then
mcellControl.Text = InstantText
End If
End Sub
Protected Overridable Sub EndEdit()
minEdit = False
Invalidate()
End Sub
Protected Overridable Sub RollBack()
mcellControl.Text = moldVal
End Sub
Protected Overridable Sub PaintText(ByVal g As Graphics, _
ByVal Bounds As Rectangle, _
ByVal Text As String, _
ByVal AlignToRight As Boolean)
Dim BackBrush As Brush = New
SolidBrush(Me.DataGridTableStyle.BackColor)
Dim ForeBrush As Brush = New
SolidBrush(Me.DataGridTableStyle.ForeColor)
PaintText(g, Bounds, Text, BackBrush, ForeBrush, AlignToRight)
End Sub
Protected Overridable Sub PaintText(ByVal g As Graphics, _
ByVal TextBounds As Rectangle, _
ByVal Text As String, _
ByVal BackBrush As Brush, _
ByVal ForeBrush As Brush, _
ByVal AlignToRight As Boolean)
Dim Rect As Rectangle = TextBounds
Dim RectF As RectangleF = RectF.op_Implicit(Rect) ' Convert
to RectangleF
Dim Format As StringFormat = New StringFormat
If AlignToRight Then
Format.FormatFlags =
StringFormatFlags.DirectionRightToLeft
End If
Select Case Me.Alignment
Case Is = HorizontalAlignment.Left
Format.Alignment = StringAlignment.Near
Case Is = HorizontalAlignment.Right
Format.Alignment = StringAlignment.Far
Case Is = HorizontalAlignment.Center
Format.Alignment = StringAlignment.Center
End Select
Format.FormatFlags = Format.FormatFlags Or
StringFormatFlags.NoWrap
g.FillRectangle(Brush:=BackBrush, Rect:=Rect)
Rect.Offset(0, myMargin)
Rect.Height -= myMargin
g.DrawString(Text, Me.DataGridTableStyle.DataGrid.Font,
ForeBrush, RectF, Format)
Format.Dispose()
End Sub
#End Region
#End Region
#Region "Public"
#Region "Events"
Public Event ColumnDirty(ByVal sender As Object, ByVal e As
System.EventArgs)
Public Event ColumnEdited(ByVal sender As Object, ByVal e As
System.EventArgs)
#End Region
#End Region
End Class
#End Region
Public Class ExtendedDataGridTextBoxColumn
Inherits ExtendedDataGridColumnStyle
#Region "Private"
#Region "Properties"
Private WithEvents tb As TextBox
#End Region
#Region "Subroutines"
Private Sub HideTextBox()
If tb.Focused Then
Me.DataGridTableStyle.DataGrid.Focus()
End If
tb.Visible = False
End Sub
Private Sub tb_TextChanged(ByVal sender As Object, ByVal e
As System.EventArgs) Handles tb.TextChanged
MyBase.ColumnStartedEditing(tb)
End Sub
#End Region
#End Region
#Region "Protected"
#Region "Functions"
Protected Overrides Function Commit(ByVal dataSource As
System.Windows.Forms.CurrencyManager, _
ByVal rowNum As Integer)
As Boolean
HideTextBox()
RowNumber = rowNum
GridDataSource = dataSource
If Not InEdit Then
Return True
End If
Try
Dim Value As Object = tb.Text
If NullText.Equals(Value) Then
Value = Convert.DBNull
End If
If Not Value = GetColumnTextAtRow(dataSource,
rowNum) Then
IsDirty = True
SetColumnValueAtRow(dataSource, rowNum, Value)
End If
Catch e As Exception
RollBack()
Return False
End Try
EndEdit()
Return True
End Function
Protected Overrides Function GetColumnTextAtRow(ByVal Source
As System.Windows.Forms.CurrencyManager, ByVal RowNum As Integer) As Object
Dim value As Object = Me.GetColumnValueAtRow(Source,
RowNum)
If value Is System.DBNull.Value Then
Return NullText
Else
Return value
End If
End Function
Protected Overrides Function GetMinimumHeight() As Integer
'Set the minimum height to the height of the combobox
Return tb.PreferredHeight + yMargin
End Function
#End Region
#Region "Subroutines"
Protected Overloads Overrides Sub Abort(ByVal RowNum As
Integer)
MyBase.Abort(RowNum)
HideTextBox()
End Sub
Protected Overloads Overrides Sub ConcedeFocus()
tb.Visible = False
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)
GridDataSource = source
RowNumber = rowNum
tb.Text = String.Empty
Dim OriginalBounds As Rectangle = bounds
Dim txt As String
OldValue = GetColumnValueAtRow(source, rowNum)
If cellIsVisible Then
bounds.Offset(xMargin, yMargin)
bounds.Width -= xMargin * 2
bounds.Height -= yMargin
tb.Bounds = bounds
tb.Visible = True
Else
tb.Bounds = OriginalBounds
tb.Visible = False
End If
If Not instantText Is Nothing Then
tb.Text = instantText
Else
tb.Text = oldvalue
End If
tb.RightToLeft =
Me.DataGridTableStyle.DataGrid.RightToLeft
tb.Focus()
If instantText Is Nothing Then
tb.SelectAll()
Else
Dim [End] As Integer = tb.Text.Length
tb.Select([End], 0)
End If
If tb.Visible Then
DataGridTableStyle.DataGrid.Invalidate(OriginalBou nds)
End If
InEdit = True
End Sub
#End Region
#End Region
#Region "Public"
#Region "Properties"
Public ReadOnly Property TextBox() As TextBox
Get
Return tb
End Get
End Property
#End Region
#Region "Subroutines"
Public Sub New()
tb = New TextBox
tb.Visible = False
CellControl = CType(tb, Control)
End Sub
#End Region
#End Region
End Class
Pat
"Mike McIntyre" wrote:
No bells ringing yet.
If you can share your DataGridColumnStyle code post it here or send it to
me: mi****@getdotnetcode.com
and I will take a look.
Mike
"pmcguire" <pm******@discussions.microsoft.com> wrote in message
news:8E**********************************@microsof t.com... By default, your derived column should be colored (highlighted) when a
row
is selected in the DataGrid. Is this not happening?
No, this is NOT happening. Mind you, I have overridden a bunch of stuff
in
my derived DataGridColumnStyles.
The DataGridColumnStyle class has a property named DataGridTableStyle
which
in turn has a DataGrid property which holds a refererence the DataGrid
hosting the DataGridColumnStyle.
In fact I found the reference to the datagrid shortly after my first post.
"FORCING" the row to paint in the DataTableStyles.BackColor after testing
for
selection doesn't work, i.e. the DataGrid thinks that the row in question
is
not selected. It seems I have overridden something that would ordinarily
set
the IsSelected for the row.
Does this ring any bells?
Thanks,
Pat
"Mike McIntyre" wrote:
The DataGridColumnStyle class has a property named DataGridTableStyle
which
in turn has a DataGrid property which holds a refererence the DataGrid
hosting the DataGridColumnStyle.
By default, your derived column should be colored (highlighted) when a
row
is selected in the DataGrid. Is this not happening? Or am I
misunderstanding your question?
--
Mike
Mike McIntyre
Visual Basic MVP
www.getdotnetcode.com
"pmcguire" <pm******@discussions.microsoft.com> wrote in message
news:C6**********************************@microsof t.com...
>I have a DataGrid control for which I have also created several new
>extended
> DataGridColumnStyles. They behave pretty nicely, but I can't figure
> out
> how
> to implement Selected Item formatting for them.
>
> In a plain vanilla DataGrid, when you click on the RowHeader, the
> appropriate row changes colors. I ASSUME this should be done in the
> Paint
> (or PaintText) override of the DataGridColumnStyle in question. My
> problem
> is that I don't know how to retrieve the DataGrid of the
> DataGridColumnStyle
> instance to test if the row is selected.
>
> Or, maybe this isn't the best way to do this. Any help?
>
> Thanks,
> --
> Pat