上一篇博文探讨了如何自定义DataGridViewColumn实现一个TreeViewColumn来在DataGridView控件中显示TreeView控件,其实我们还可以继续发挥想象,自定义其他的列类型,下面介绍一个脚本编辑器列类型,我这里取名ScriptTextEditorColumn,当用户单击DataGridView的ScriptTextEditorColumn时,单元格右边会出现一个按钮,单击按钮会弹出一个脚本编辑器窗体,用户可以在窗体中进行代码维护,然后回写到单元格中。
用人会问,这个控件有啥实际作用,其实结合动态编译的技术,在datagridview中进行取值公式的模板设定,也就是在对应的单元格中设置C#脚本,然后动态执行后呈现结果到一个datagridview单元格中,这样就实现了动态配置datagridview后台计算逻辑的目的,当然实现这样的功能还需要大量的工作,但是主要的思路就是这样。
1 ScriptTextEditorColumn1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Linq;4usingSystem.Text;5usingSystem.Windows.Forms;67namespaceHost_Controls_in_Windows_Forms_DataGridView_Cells8{9publicclassScriptTextEditorColumn : DataGridViewColumn10{11publicScriptTextEditorColumn()12:base(newScriptTextEditorCell())13{14}1516publicoverrideDataGridViewCell CellTemplate17{18get19{20returnbase.CellTemplate;21}22set23{24//Ensure that the cell used for the template is a ScriptTextEditorCell.25if(value !=null&&26!value.GetType().IsAssignableFrom(typeof(ScriptTextEditorCell)))27{28thrownewInvalidCastException("Must be a ScriptTextEditorCell");29}30base.CellTemplate =value;31}32}33}3435//----------------------------------------------------------------------36publicclassScriptTextEditorCell : DataGridViewTextBoxCell37{3839publicScriptTextEditorCell()40:base()41{4243}4445publicoverridevoidInitializeEditingControl(introwIndex,object46initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)47{48//Set the value of the editing control to the current cell value.49base.InitializeEditingControl(rowIndex, initialFormattedValue,50dataGridViewCellStyle);51ScriptTextEditingControl ctl =52DataGridView.EditingControlasScriptTextEditingControl;53//Use the default row value when ValuePRoperty is null.54if(this.Value ==null)55{56ctl.textBox1.Text = (String)this.DefaultNewRowValue;57}58else59{60ctl.textBox1.Text = (String)this.Value;61}62}6364publicoverrideType EditType65{66get67{68//Return the type of the editing control that CalendarCell uses.69returntypeof(ScriptTextEditingControl);70}71}7273publicoverrideType ValueType74{75get76{77//Return the type of the value that CalendarCell contains.7879returntypeof(String);80}81}8283publicoverrideobjectDefaultNewRowValue84{85get86{87//Use the current date and time as the default value.88stringcode =@"89#region90//jackwangcumt91#endregion92using System;93using System.Collections.Generic;94using System.ComponentModel;95using System.Drawing;96using System.Data;97using System.Linq;98using System.Text;99using System.Windows.Forms;100namespace Host_Controls_in_Windows_Forms_DataGridView_Cells101{102public partial class SourceTextBox : UserControl103{104public SourceTextBox()105{106InitializeComponent();107this.textBox1.Location = this.Location;108this.textBox1.Width = this.Width;109this.textBox1.Height = this.Height;110}111protected void OnValueChanged(string text)112{113this.textBox1.Text = text;114}115116private void btnSource_Click(object sender, EventArgs e)117{118ScriptEditor frm = new ScriptEditor(this.textBox1.Text);119frm.ShowDialog();120this.textBox1.Text = frm.fastColoredTextBox1.Text;121}122}123}124";125returncode;126}127}128}129//-----------------------------------------------------------------130131classScriptTextEditingControl : SourceTextBox, IDataGridViewEditingControl132{133DataGridView dataGridView;134privateboolvalueChanged =false;135introwIndex;136137publicScriptTextEditingControl()138{139//文本变更更新到cell140this.textBox1.TextChanged +=newEventHandler(textBox1_TextChanged);141}142143voidtextBox1_TextChanged(objectsender, EventArgs e)144{145//Notify the DataGridView that the contents of the cell146//have changed.147valueChanged =true;148this.EditingControlDataGridView.NotifyCurrentCellDirty(true);149//调用SourceTextBox的OnValueChanged(string Text)150base.OnValueChanged(this.textBox1.Text);151}152153//Implements the IDataGridViewEditingControl.EditingControlFormattedValue154//property.155publicobjectEditingControlFormattedValue156{157get158{159returnthis.textBox1.Text;160}161set162{163if(valueisString)164{165try166{167//This will throw an exception of the string is168//null, empty, or not in the format of a date.169this.textBox1.Text=((String)value);170}171catch172{173//In the case of an exception, just use the174//default value so we're not left with a null175//value.176this.textBox1.Text ="jackwangcumt>>error";177}178}179}180}181182//Implements the183//IDataGridViewEditingControl.GetEditingControlFormattedValue method.184publicobjectGetEditingControlFormattedValue(185DataGridViewDataErrorContexts context)186{187returnEditingControlFormattedValue;188}189190//Implements the191//IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.192publicvoidApplyCellStyleToEditingControl(193DataGridViewCellStyle dataGridViewCellStyle)194{195this.Font =dataGridViewCellStyle.Font;196//this.CalendarForeColor = dataGridViewCellStyle.ForeColor;197//this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;198}199200//Implements the IDataGridViewEditingControl.EditingControlRowIndex201//property.202publicintEditingControlRowIndex203{204get205{206returnrowIndex;207}208set209{210rowIndex =value;211}212}213214//Implements the IDataGridViewEditingControl.EditingControlWantsInputKey215//method.216publicboolEditingControlWantsInputKey(217Keys key,booldataGridViewWantsInputKey)218{219//Let the DateTimePicker handle the keys listed.220switch(key &Keys.KeyCode)221{222caseKeys.Left:223caseKeys.Up:224caseKeys.Down:225caseKeys.Right:226caseKeys.Home:227caseKeys.End:228caseKeys.PageDown:229caseKeys.PageUp:230returntrue;231default:232return!dataGridViewWantsInputKey;233}234}235236//Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit237//method.238publicvoidPrepareEditingControlForEdit(boolselectAll)239{240//No preparation needs to be done.241}242243//Implements the IDataGridViewEditingControl244//.RepositionEditingControlOnValueChange property.245publicboolRepositionEditingControlOnValueChange246{247get248{249returnfalse;250}251}252253//Implements the IDataGridViewEditingControl254//.EditingControlDataGridView property.255publicDataGridView EditingControlDataGridView256{257get258{259returndataGridView;260}261set262{263dataGridView =value;264}265}266267//Implements the IDataGridViewEditingControl268//.EditingControlValueChanged property.269publicboolEditingControlValueChanged270{271get272{273returnvalueChanged;274}275set276{277valueChanged =value;278}279}280281//Implements the IDataGridViewEditingControl282//.EditingPanelCursor property.283publicCursor EditingPanelCursor284{285get286{287returnbase.Cursor;288}289}290291protectedoverridevoidOnTextChanged(EventArgs e)292{293//Notify the DataGridView that the contents of the cell294//have changed.295valueChanged =true;296this.EditingControlDataGridView.NotifyCurrentCellDirty(true);297base.OnTextChanged(e);298299}300301}302303304305}
2 SourceTextBox1usingSystem;2usingSystem.Collections.Generic;3usingSystem.ComponentModel;4usingSystem.Drawing;5usingSystem.Data;6usingSystem.Linq;7usingSystem.Text;8usingSystem.Windows.Forms;910namespaceHost_Controls_in_Windows_Forms_DataGridView_Cells11{12publicpartialclassSourceTextBox : UserControl13{14publicSourceTextBox()15{16InitializeComponent();17this.textBox1.Location =this.Location;18this.textBox1.Width =this.Width;19this.textBox1.Height =this.Height;20}21protectedvoidOnValueChanged(stringtext)22{23this.textBox1.Text =text;24}2526privatevoidbtnSource_Click(objectsender, EventArgs e)27{28ScriptEditor frm =newScriptEditor(this.textBox1.Text);29frm.ShowDialog();30this.textBox1.Text =frm.fastColoredTextBox1.Text;31}32}33}
[flash=500,400]http://s1.knowsky.com/20160211/kkyvtafmzvz41.gif[/flash][flash=500,400]http://s1.knowsky.com/20160211/0t4enkrxgyf41.gif[/flash]1namespaceHost_Controls_in_Windows_Forms_DataGridView_Cells2{3partialclassSourceTextBox4{5///<summary>6///必需的设计器变量。7///</summary>8privateSystem.ComponentModel.IContainer components =null;910///<summary>11///清理所有正在使用的资源。12///</summary>13///<param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>14protectedoverridevoidDispose(booldisposing)15{16if(disposing && (components !=null))17{18components.Dispose();19}20base.Dispose(disposing);21}2223#region组件设计器生成的代码2425///<summary>26///设计器支持所需的方法 - 不要27///使用代码编辑器修改此方法的内容。28///</summary>29privatevoidInitializeComponent()30{31this.textBox1 =newSystem.Windows.Forms.TextBox();32this.btnSource =newSystem.Windows.Forms.Button();33this.SuspendLayout();34//35//textBox136//37this.textBox1.BorderStyle =System.Windows.Forms.BorderStyle.None;38this.textBox1.Location =newSystem.Drawing.Point(3,3);39this.textBox1.Margin =newSystem.Windows.Forms.Padding(4);40this.textBox1.Multiline =true;41this.textBox1.Name ="textBox1";42this.textBox1.Size =newSystem.Drawing.Size(175,21);43this.textBox1.TabIndex =1;44//45//btnSource46//47this.btnSource.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top |System.Windows.Forms.AnchorStyles.Bottom)48|System.Windows.Forms.AnchorStyles.Right)));49this.btnSource.BackColor =System.Drawing.Color.Transparent;50this.btnSource.BackgroundImage =global::Host_Controls_in_Windows_Forms_DataGridView_Cells.Resource.setting;51this.btnSource.BackgroundImageLayout =System.Windows.Forms.ImageLayout.Zoom;52this.btnSource.FlatAppearance.BorderColor =System.Drawing.Color.White;53this.btnSource.FlatAppearance.BorderSize =0;54this.btnSource.FlatStyle =System.Windows.Forms.FlatStyle.Flat;55this.btnSource.Font =newSystem.Drawing.Font("新宋体", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));56this.btnSource.Location =newSystem.Drawing.Point(159, -1);57this.btnSource.Margin =newSystem.Windows.Forms.Padding(0);58this.btnSource.Name ="btnSource";59this.btnSource.Size =newSystem.Drawing.Size(19,25);60this.btnSource.TabIndex =0;61this.btnSource.UseVisualStyleBackColor =false;62this.btnSource.Click +=newSystem.EventHandler(this.btnSource_Click);63//64//SourceTextBox65//66this.AutoScaleDimensions =newSystem.Drawing.SizeF(6F, 12F);67this.AutoScaleMode =System.Windows.Forms.AutoScaleMode.Font;68this.Controls.Add(this.btnSource);69this.Controls.Add(this.textBox1);70this.Margin =newSystem.Windows.Forms.Padding(0);71this.Name ="SourceTextBox";72this.Size =newSystem.Drawing.Size(178,26);73this.ResumeLayout(false);74this.PerformLayout();7576}7778#endregion7980publicSystem.Windows.Forms.Button btnSource;81publicSystem.Windows.Forms.TextBox textBox1;82}83}
View Code
3 效果[flash=500,400]http://s1.knowsky.com/20160211/whafsvhknhq42.jpg[/flash]