C#如何自定义DataGridViewColumn来显示TreeView

王朝学院·作者佚名  2016-08-28
窄屏简体版  字體: 小  |  中  |  大  |  超大  

我们可以自定义DataGridView的DataGridViewColumn来实现自定义的列,下面介绍一下如何通过扩展DataGridViewColumn来实现一个TreeViewColumn

1 TreeViewColumn类TreeViewColumn继承自DataGridViewColumn,为了动态给TreeViewColumn传入一个TreeView,这里暴露出一个公共属性_root,可以绑定一个初始化的TreeView. 另外需要重写DataGridCell类型的CellTemplate,这里返还一个TreeViewCell(需要自定义)

1///<summary>2///Host TreeView In DataGridView Cell3///</summary>4publicclassTreeViewColumn : DataGridViewColumn5{6publicTreeViewColumn()7:base(newTreeViewCell())8{9}10[Description("Set TreeView Root in DataGridView Cell"), Category("TreeView")]11publicTreeView _root12{13get{returnRoots.tree;}14set{Roots.tree=value;}15}16publicoverrideDataGridViewCell CellTemplate17{18get19{20returnbase.CellTemplate;21}22set23{24//Ensure that the cell used for the template is a TreeViewCell.25if(value !=null&&26!value.GetType().IsAssignableFrom(typeof(TreeViewCell)))27{28thrownewInvalidCastException("Must be a TreeViewCell");29}30base.CellTemplate =value;31}32}33}

2 TreeViewCell类 上面TreeViewColumn重写了CellTemplate,返回的就是自定义的TreeViewCell,这里就是具体实现其逻辑。一般来说选择树控件的节点后,返回的是一个文本信息,是文本类型,可以继承DataGridViewTextBoxCell,并重写InitializeEditingControl来进行自定义的DataGridView.EditingControl (编辑控件)。

1publicclassTreeViewCell : DataGridViewTextBoxCell2{34publicTreeViewCell()5:base()6{78//初始设置9}1011publicoverridevoidInitializeEditingControl(introwIndex,object12initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)13{14//Set the value of the editing control to the current cell value.15base.InitializeEditingControl(rowIndex, initialFormattedValue,16dataGridViewCellStyle);17TreeViewEditingControl ctl =18DataGridView.EditingControlasTreeViewEditingControl;19//Use the default row value when ValuePRoperty is null.20if(this.Value ==null)21{2223ctl.SelectedNode =newTreeNode(this.DefaultNewRowValue.ToString());24}25else26{27ctl.SelectedNode =newTreeNode(this.Value.ToString());28}29}3031publicoverrideType EditType32{33get34{35//Return the type of the editing control that CalendarCell uses.36returntypeof(TreeViewEditingControl);37}38}3940publicoverrideType ValueType41{42get43{44//Return the type of the value that CalendarCell contains.45returntypeof(String);46}47}4849publicoverrideobjectDefaultNewRowValue50{51get52{53//Use the current date and time as the default value.54return"";55}56}57}

3 TreeViewEditingControl类TreeViewEditingControl为编辑控件,当用户编辑TreeViewCell时,显示的为树编辑控件,需要继承TreeView,同时实现IDataGridViewEditingControl接口,实现以下方法:

[flash=500,400]http://s1.knowsky.com/20160211/q4rwtppavu217.jpg[/flash]

1publicclassTreeViewEditingControl : TreeView, IDataGridViewEditingControl2{3DataGridView dataGridView;4privateboolvalueChanged =false;5introwIndex;6publicTreeViewEditingControl()7{8try9{10//必须加Roots.tree.Nodes[0].Clone() 否则报错 不能在多处增添或插入项,必须首先将其从当前位置移除或将其克隆11this.Nodes.Add(Roots.tree.Nodes[0].Clone()asTreeNode);12this.SelectedNode =this.Nodes[0];131415}16catch(Exception ex)17{18MessageBox.Show(ex.Message);19}202122}2324//Implements the IDataGridViewEditingControl.EditingControlFormattedValue25//property.26publicobjectEditingControlFormattedValue27{28get29{30returnthis.SelectedNode.Text;31}32set33{34if(valueisString)35{36try37{38//This will throw an exception of the string is39//null, empty, or not in the format of a date.40this.SelectedNode =newTreeNode((String)value);4142}43catch44{45//In the case of an exception, just use the46//default value so we're not left with a null47//value.48this.SelectedNode =newTreeNode("");49}50}51}52}5354//Implements the55//IDataGridViewEditingControl.GetEditingControlFormattedValue method.56publicobjectGetEditingControlFormattedValue(57DataGridViewDataErrorContexts context)58{59returnEditingControlFormattedValue;60}6162//Implements the63//IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.64publicvoidApplyCellStyleToEditingControl(65DataGridViewCellStyle dataGridViewCellStyle)66{67this.Font =dataGridViewCellStyle.Font;68this.ForeColor =dataGridViewCellStyle.ForeColor;69this.BackColor =dataGridViewCellStyle.BackColor;70}7172//Implements the IDataGridViewEditingControl.EditingControlRowIndex73//property.74publicintEditingControlRowIndex75{76get77{78returnrowIndex;79}80set81{82rowIndex =value;83}84}8586//Implements the IDataGridViewEditingControl.EditingControlWantsInputKey87//method.88publicboolEditingControlWantsInputKey(89Keys key,booldataGridViewWantsInputKey)90{91//Let the TreeViewPicker handle the keys listed.92switch(key &Keys.KeyCode)93{94caseKeys.Left:95caseKeys.Up:96caseKeys.Down:97caseKeys.Right:98caseKeys.Home:99caseKeys.End:100caseKeys.PageDown:101caseKeys.PageUp:102returntrue;103default:104return!dataGridViewWantsInputKey;105}106}107108//Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit109//method.110publicvoidPrepareEditingControlForEdit(boolselectAll)111{112//No preparation needs to be done.113}114115//Implements the IDataGridViewEditingControl116//.RepositionEditingControlOnValueChange property.117publicboolRepositionEditingControlOnValueChange118{119get120{121returnfalse;122}123}124125//Implements the IDataGridViewEditingControl126//.EditingControlDataGridView property.127publicDataGridView EditingControlDataGridView128{129get130{131returndataGridView;132}133set134{135dataGridView =value;136}137}138139//Implements the IDataGridViewEditingControl140//.EditingControlValueChanged property.141publicboolEditingControlValueChanged142{143get144{145returnvalueChanged;146}147set148{149valueChanged =value;150}151}152153//Implements the IDataGridViewEditingControl154//.EditingPanelCursor property.155publicCursor EditingPanelCursor156{157get158{159returnbase.Cursor;160}161}162163protectedoverridevoidOnAfterExpand(TreeViewEventArgs e)164{165base.OnAfterExpand(e);166this.dataGridView.Columns[this.dataGridView.CurrentCell.ColumnIndex].Width =this.Width+10;167this.dataGridView.Rows[this.dataGridView.CurrentCell.RowIndex].Height =this.Height+20;168169}170protectedoverridevoidOnAfterSelect(TreeViewEventArgs e)171{172//Notify the DataGridView that the contents of the cell173//have changed.174valueChanged =true;175this.EditingControlDataGridView.NotifyCurrentCellDirty(true);176base.OnAfterSelect(e);177178}179180}

为了在不同类之间传递参数,定义一个全局静态类:

1///<summary>2///静态类的静态属性,用于在不同class间传递参数3///</summary>4publicstaticclassRoots5{6//从前台绑定树7publicstaticTreeView tree =null;8}

完整代码为:

[flash=500,400]http://s1.knowsky.com/20160211/c3s5exovqvz17.gif[/flash][flash=500,400]http://s1.knowsky.com/20160211/d0utfiulqom17.gif[/flash]1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Linq;4usingSystem.Text;5usingSystem.Windows.Forms;6usingSystem.ComponentModel;7namespaceHost_Controls_in_Windows_Forms_DataGridView_Cells8{9///<summary>10///静态类的静态属性,用于在不同class间传递参数11///</summary>12publicstaticclassRoots13{14//从前台绑定树15publicstaticTreeView tree =null;16}17///<summary>18///Host TreeView In DataGridView Cell19///</summary>20publicclassTreeViewColumn : DataGridViewColumn21{22publicTreeViewColumn()23:base(newTreeViewCell())24{25}26[Description("Set TreeView Root in DataGridView Cell"), Category("TreeView")]27publicTreeView _root28{29get{returnRoots.tree;}30set{Roots.tree=value;}31}32publicoverrideDataGridViewCell CellTemplate33{34get35{36returnbase.CellTemplate;37}38set39{40//Ensure that the cell used for the template is a TreeViewCell.41if(value !=null&&42!value.GetType().IsAssignableFrom(typeof(TreeViewCell)))43{44thrownewInvalidCastException("Must be a TreeViewCell");45}46base.CellTemplate =value;47}48}49}5051//----------------------------------------------------------------------52publicclassTreeViewCell : DataGridViewTextBoxCell53{5455publicTreeViewCell()56:base()57{5859//初始设置60}6162publicoverridevoidInitializeEditingControl(introwIndex,object63initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)64{65//Set the value of the editing control to the current cell value.66base.InitializeEditingControl(rowIndex, initialFormattedValue,67dataGridViewCellStyle);68TreeViewEditingControl ctl =69DataGridView.EditingControlasTreeViewEditingControl;70//Use the default row value when Value property is null.71if(this.Value ==null)72{7374ctl.SelectedNode =newTreeNode(this.DefaultNewRowValue.ToString());75}76else77{78ctl.SelectedNode =newTreeNode(this.Value.ToString());79}80}8182publicoverrideType EditType83{84get85{86//Return the type of the editing control that CalendarCell uses.87returntypeof(TreeViewEditingControl);88}89}9091publicoverrideType ValueType92{93get94{95//Return the type of the value that CalendarCell contains.96returntypeof(String);97}98}99100publicoverrideobjectDefaultNewRowValue101{102get103{104//Use the current date and time as the default value.105return"";106}107}108}109//-----------------------------------------------------------------110111publicclassTreeViewEditingControl : TreeView, IDataGridViewEditingControl112{113DataGridView dataGridView;114privateboolvalueChanged =false;115introwIndex;116publicTreeViewEditingControl()117{118try119{120//必须加Roots.tree.Nodes[0].Clone() 否则报错 不能在多处增添或插入项,必须首先将其从当前位置移除或将其克隆121this.Nodes.Add(Roots.tree.Nodes[0].Clone()asTreeNode);122this.SelectedNode =this.Nodes[0];123124125}126catch(Exception ex)127{128MessageBox.Show(ex.Message);129}130131132}133134//Implements the IDataGridViewEditingControl.EditingControlFormattedValue135//property.136publicobjectEditingControlFormattedValue137{138get139{140returnthis.SelectedNode.Text;141}142set143{144if(valueisString)145{146try147{148//This will throw an exception of the string is149//null, empty, or not in the format of a date.150this.SelectedNode =newTreeNode((String)value);151152}153catch154{155//In the case of an exception, just use the156//default value so we're not left with a null157//value.158this.SelectedNode =newTreeNode("");159}160}161}162}163164//Implements the165//IDataGridViewEditingControl.GetEditingControlFormattedValue method.166publicobjectGetEditingControlFormattedValue(167DataGridViewDataErrorContexts context)168{169returnEditingControlFormattedValue;170}171172//Implements the173//IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.174publicvoidApplyCellStyleToEditingControl(175DataGridViewCellStyle dataGridViewCellStyle)176{177this.Font =dataGridViewCellStyle.Font;178this.ForeColor =dataGridViewCellStyle.ForeColor;179this.BackColor =dataGridViewCellStyle.BackColor;180}181182//Implements the IDataGridViewEditingControl.EditingControlRowIndex183//property.184publicintEditingControlRowIndex185{186get187{188returnrowIndex;189}190set191{192rowIndex =value;193}194}195196//Implements the IDataGridViewEditingControl.EditingControlWantsInputKey197//method.198publicboolEditingControlWantsInputKey(199Keys key,booldataGridViewWantsInputKey)200{201//Let the TreeViewPicker handle the keys listed.202switch(key &Keys.KeyCode)203{204caseKeys.Left:205caseKeys.Up:206caseKeys.Down:207caseKeys.Right:208caseKeys.Home:209caseKeys.End:210caseKeys.PageDown:211caseKeys.PageUp:212returntrue;213default:214return!dataGridViewWantsInputKey;215}216}217218//Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit219//method.220publicvoidPrepareEditingControlForEdit(boolselectAll)221{222//No preparation needs to be done.223}224225//Implements the IDataGridViewEditingControl226//.RepositionEditingControlOnValueChange property.227publicboolRepositionEditingControlOnValueChange228{229get230{231returnfalse;232}233}234235//Implements the IDataGridViewEditingControl236//.EditingControlDataGridView property.237publicDataGridView EditingControlDataGridView238{239get240{241returndataGridView;242}243set244{245dataGridView =value;246}247}248249//Implements the IDataGridViewEditingControl250//.EditingControlValueChanged property.251publicboolEditingControlValueChanged252{253get254{255returnvalueChanged;256}257set258{259valueChanged =value;260}261}262263//Implements the IDataGridViewEditingControl264//.EditingPanelCursor property.265publicCursor EditingPanelCursor266{267get268{269returnbase.Cursor;270}271}272273protectedoverridevoidOnAfterExpand(TreeViewEventArgs e)274{275base.OnAfterExpand(e);276this.dataGridView.Columns[this.dataGridView.CurrentCell.ColumnIndex].Width =this.Width+10;277this.dataGridView.Rows[this.dataGridView.CurrentCell.RowIndex].Height =this.Height+20;278279}280protectedoverridevoidOnAfterSelect(TreeViewEventArgs e)281{282//Notify the DataGridView that the contents of the cell283//have changed.284valueChanged =true;285this.EditingControlDataGridView.NotifyCurrentCellDirty(true);286base.OnAfterSelect(e);287288}289290}291292293294}

View Code

[flash=500,400]http://s1.knowsky.com/20160211/vcikam4bbwv17.jpg[/flash]

当编辑无误后,可以在添加列的时候看到TreeViewColumn类型。此类型暴露出一个_root属性,可以绑定外部的一个带数据的TreeView。

[flash=500,400]http://s1.knowsky.com/20160211/z1jmr2f4axp17.jpg[/flash]

运行代码,单击单元格,进入编辑状态,可以看到如下界面:

[flash=500,400]http://s1.knowsky.com/20160211/4m0ne1s2ssv18.jpg[/flash]

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航