最近谈论较多的就是datagrid,特别新手最是郁闷为何没有更好的控件,来满足自已的需求。 
其实通过重写可以达到很多不同的功能体验,在这里我们仅仅讨论关于datagridcolumnstyle重写的问题 
========================================== 
1。重写textbox:
public class xp_textbox 
inherits system.windows.forms.textbox 
#region " windows "
public sub new() 
mybase.new() 
initializecomp
end sub
protected overloads overrides sub dispose(byval disposing as boolean) 
if disposing then 
if not (comp is nothing) then 
components.dispose() 
end if 
end if 
mybase.dispose(disposing) 
end sub 
'windows 
private comp as system.componentmodel.ic 
<system.diagnostics.debuggerstepthrough()> private sub initializecomp 
' 
'textbox 
' 
me.enablec = true 
me.enablepaste = true 
me.name = "textbox" 
end sub
#end region
#region " variables "
private m_enpaste as boolean = true 
private m_enc as boolean = true 
#end region
#region " property "
property enablepaste() as boolean 
get 
return m_enpaste 
end get 
set(byval value as boolean) 
m_enpaste = value 
me.invalidate() 
end set 
end property 
property enablec as boolean 
get 
return m_enc 
end get 
set(byval value as boolean) 
m_enc = value 
me.invalidate() 
end set 
end property 
#end region
protected overrides sub wndproc(byref m as system.windows.forms.message) 
select case m.msg 
case &h302 'paste 
raiseevent pasteevent() 
if not m_enpaste then return 
case &h7b 'c 
if not m_enc then return 
end select 
mybase.wndproc(m) 
end sub 
public event pasteevent()
end class
2。重写datagridcolumnstyle(重点介绍内容):
imports system.drawing 
imports system.windows.forms 
public notinheritable class datagridtextboxcolumnstyle 
inherits system.windows.forms.datagridcolumnstyle 
#region "declare property"
private withevents m_textbox as new landlord.component.xp_textbox 
private isediting as boolean 
private editingrow as integer = -1 
private m_oldvalue as string 
#end region
#region " windows "
sub new() 
me.m_textbox.visible = false 
end sub 
public sub new(byval c as system.componentmodel.ic 
myclass.new() 
container.add(me) 
end sub 
protected overloads overrides sub dispose(byval disposing as boolean) 
if disposing then 
if not (comp is nothing) then 
components.dispose() 
end if 
end if 
mybase.dispose(disposing) 
end sub 
private comp as system.componentmodel.ic
<system.diagnostics.debuggerstepthrough()> private sub initializecomp 
comp = new system.componentmodel.c 
end sub 
#end region
#region "get functi
protected overrides function getminimumheight() as integer 
return m_textbox.preferredheight + 2 
end function 
protected overrides function getpreferredheight(byval g as system.drawing.graphics, byval value as object) as integer 
return m_textbox.preferredheight + 2 
end function 
protected overrides function getpreferredsize(byval g as system.drawing.graphics, byval value as object) as system.drawing.size 
return new size(50, m_textbox.preferredheight + 2) 
end function 
#end region
#region "paint"
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 brush_for as brush = new solidbrush(me.datagridtablestyle.forecolor) 
dim brush_bak as brush = new solidbrush(me.datagridtablestyle.backcolor) 
paint(g, bounds, [source], rownum, brush_bak, brush_for, aligntoright) 
brush_for.dispose() 
brush_bak.dispose() 
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 brush, byval forebrush as brush, byval aligntoright as boolean) 
dim str as string 
if isdbnull(getcolumnvalueatrow([source], rownum)) then 
str = me.nulltext 
else 
str = ctype(getcolumnvalueatrow([source], rownum), string) 
end if 
dim brush as brush = backbrush 
dim rect as system.drawing.rectangle = bounds 
g.fillrectangle(brush, rect) 
if me.isediting and editingrow = rownum then 
brush = new solidbrush(color.white) 
g.fillrectangle(brush, bounds) 
end if 
rect.offset(0, 2) 
rect.height -= 2 
brush = new solidbrush(me.datagridtablestyle.forecolor) 
if me.datagridtablestyle.datagrid.isselected(rownum) then 
brush = new solidbrush(me.datagridtablestyle.selecti 
dim rectf as rectanglef = new rectanglef(bounds.x, bounds.y, bounds.width, bounds.height) 
g.fillrectangle(brush, rectf) 
brush = new solidbrush(me.datagridtablestyle.selecti 
end if 
if me.alignment = horizontalalignment.center then 
dim w as integer = g.measurestring(str, me.datagridtablestyle.datagrid.f new sizef(bounds.width, bounds.height)).width 
rect.x = rect.x + (bounds.width – w) / 2 
elseif me.alignment = horizontalalignment.right then 
dim w as integer = g.measurestring(str, me.datagridtablestyle.datagrid.f new sizef(bounds.width, bounds.height)).width 
rect.x = bounds.right – w 
end if 
g.drawstring(str, me.datagridtablestyle.datagrid.f brush, rect.x, rect.y) 
brush.dispose() 
end sub 
#end region
#region "overrides method"
protected overrides function commit(byval datasource as system.windows.forms.currencymanager, byval rownum as integer) as boolean 
me.m_textbox.bounds = rectangle.empty 
if not me.isediting then 
return true 
end if 
editingrow = -1 
isediting = false 
try 
dim value as object 
value = m_textbox.text 
if nulltext.equals(value) then 
value = system.dbnull.value 
end if 
setcolumnvalueatrow(datasource, rownum, value) 
catch ex as exception 
abort(rownum) 
return false 
end try 
invalidate() 
return true 
end function 
protected overrides sub abort(byval rownum as integer) 
me.m_textbox.text = m_oldvalue 
editingrow = -1
if m_textbox.focused then 
me.datagridtablestyle.datagrid.focus() 
end if 
me.m_textbox.visible = false 
me.isediting = false 
me.invalidate() 
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) 
editingrow = rownum 
isediting = true 
dim value as string 
if isdbnull(getcolumnvalueatrow(source, rownum)) then 
value = me.nulltext 
else 
value = ctype(getcolumnvalueatrow(source, rownum), string) 
end if 
m_oldvalue = value 
if cellisvisible then 
if not me.readonly then 
me.m_textbox.bounds = new rectangle(bounds.x + 1, bounds.y + 1, bounds.width – 2, bounds.height – 2) 
me.m_textbox.text = value 
me.m_textbox.select() 
me.m_textbox.focus() 
me.m_textbox.selectall() 
me.m_textbox.visible = true 
me.m_textbox.flat = true 
end if 
else 
me.m_textbox.text = value 
'滚动时会丢失焦点 
'me.m_textbox.visible = false 
end if 
if me.m_textbox.visible then 
datagridtablestyle.datagrid.invalidate(bounds) 
end if 
end sub 
protected overloads overrides sub setdatagridincolumn(byval value as system.windows.forms.datagrid) 
mybase.setdatagridincolumn(value) 
if not m_textbox.parent is nothing then 
m_textbox.parent.controls.remove(me.m_textbox) 
end if 
if not value is nothing then 
value.controls.add(me.m_textbox) 
end if 
end sub 
protected overrides sub c 
editingrow = -1 
'否则先点到新增行,再回选非新行格时该列最后一行的值变为(null) 
isediting = false 
me.m_textbox.visible = false 
invalidate() 
end sub 
protected overrides sub enternullvalue() 
me.m_textbox.text = me.nulltext 
end sub 
private sub m_textbox_keypress(byval sender as object, byval e as system.windows.forms.keypresseventargs) handles m_textbox.keypress 
if not char.iscontrol(e.keychar) then 
me.isediting = true 
mybase.columnstartedediting(m_textbox) 
end if 
end sub 
private sub m_textbox_pasteevent() handles m_textbox.pasteevent 
me.isediting = true 
me.columnstartedediting(m_textbox) 
end sub 
#end region
end class
3。使用: 
新建一个空窗体,拖入datagrid,窗体load事件中代码如下 
private idtb_temp as new datatable 
private sub form1_load(byval sender as system.object, byval e as system.eventargs) handles mybase.load
idtb_temp = new datatable("nametable") 
idtb_temp.columns.add(new datacolumn("normal")) 
idtb_temp.columns.add(new datacolumn("textbox1")) 
idtb_temp.columns.add(new datacolumn("combobox1")) 
dim datecolumns as datacolumn 
datecolumns = new datacolumn("datetime1", type.gettype("system.datetime")) 
idtb_temp.columns.add(datecolumns) 
idtb_temp.columns.add(new datacolumn("checkbox1", type.gettype("system.boolean"))) 
dim idrw_row as datarow 
dim i as integer 
for i = 0 to 20 
idrw_row = idtb_temp.newrow 
idrw_row.item("normal") = "names" 
idrw_row.item("textbox1") = "nick" 
idrw_row.item("combobox1") = i.tostring 
idrw_row.item("datetime1") = "2004-06-04" 
idrw_row.item("checkbox1") = true 
idtb_temp.rows.add(idrw_row) 
next 
me.datagrid1.datasource = idtb_temp
dim mygridstyle as windows.forms.datagridtablestyle = new windows.forms.datagridtablestyle 
mygridstyle.mappingname = "nametable" 
mygridstyle.preferredrowheight = 30 
mygridstyle.selecti = color.blue 
mygridstyle.backcolor = color.yellow 
dim c1 as windows.forms.datagridtextboxcolumn = new windows.forms.datagridtextboxcolumn 
with c1 
.mappingname = "normal" 
.width = 100 
.headertext = "normal" 
.alignment = horizontalalignment.center 
end with 
mygridstyle.gridcolumnstyles.add(c1) 
dim c2 as landlord.component.draggrid.datagridtextboxcolumnstyle = new landlord.component.draggrid.datagridtextboxcolumnstyle 
with c2 
.mappingname = "textbox1" 
.width = 100 
.headertext = "textbox1" 
end with 
mygridstyle.gridcolumnstyles.add(c2) 
dim c3 as landlord.component.draggrid.datagridcomboboxcolumnstyle = new landlord.component.draggrid.datagridcomboboxcolumnstyle 
with c3 
.mappingname = "combobox1" 
.headertext = "combobox1" 
.width = 100 
.additem("111") 
.additem("222") 
.alignment = horizontalalignment.center 
end with 
mygridstyle.gridcolumnstyles.add(c3) 
dim c4 as landlord.component.draggrid.datagriddatetimepickercolumnstyle = new landlord.component.draggrid.datagriddatetimepickercolumnstyle 
with c4 
.mappingname = "datetime1" 
.headertext = "datetime1" 
.width = "100" 
.alignment = horizontalalignment.center 
end with 
mygridstyle.gridcolumnstyles.add(c4) 
dim c5 as landlord.component.draggrid.datagridcheckboxcolumnstyle = new landlord.component.draggrid.datagridcheckboxcolumnstyle 
with c5 
.mappingname = "checkbox1" 
.headertext = "checkbox1" 
.width = 100 
.truecolor = color.red 
end with 
mygridstyle.gridcolumnstyles.add(c5) 
me.datagrid1.tablestyles.clear() 
me.datagrid1.tablestyles.add(mygridstyle) 
end sub
4。说明: 
其他控件的加入原理基本一样,这里就不重复了