上一篇博文探讨了如何自定义DataGridViewColumn实现一个TreeViewColumn来在DataGridView控件中显示TreeView控件,其实我们还可以继续发挥想象,自定义其他的列类型,下面介绍一个脚本编辑器列类型,我这里取名ScriptTextEditorColumn,当用户单击DataGridView的ScriptTextEditorColumn时,单元格右边会出现一个按钮,单击按钮会弹出一个脚本编辑器窗体,用户可以在窗体中进行代码维护,然后回写到单元格中。

  用人会问,这个控件有啥实际作用,其实结合动态编译的技术,在datagridview中进行取值公式的模板设定,也就是在对应的单元格中设置C#脚本,然后动态执行后呈现结果到一个datagridview单元格中,这样就实现了动态配置datagridview后台计算逻辑的目的,当然实现这样的功能还需要大量的工作,但是主要的思路就是这样。

1 ScriptTextEditorColumn

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms; namespace Host_Controls_in_Windows_Forms_DataGridView_Cells
{
public class ScriptTextEditorColumn : DataGridViewColumn
{
public ScriptTextEditorColumn()
: base(new ScriptTextEditorCell())
{
} public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
// Ensure that the cell used for the template is a ScriptTextEditorCell.
if (value != null &&
!value.GetType().IsAssignableFrom(typeof(ScriptTextEditorCell)))
{
throw new InvalidCastException("Must be a ScriptTextEditorCell");
}
base.CellTemplate = value;
}
}
} //----------------------------------------------------------------------
public class ScriptTextEditorCell : DataGridViewTextBoxCell
{ public ScriptTextEditorCell()
: base()
{ } public override void InitializeEditingControl(int rowIndex, object
initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
// Set the value of the editing control to the current cell value.
base.InitializeEditingControl(rowIndex, initialFormattedValue,
dataGridViewCellStyle);
ScriptTextEditingControl ctl =
DataGridView.EditingControl as ScriptTextEditingControl;
// Use the default row value when Value property is null.
if (this.Value == null)
{
ctl.textBox1.Text = (String)this.DefaultNewRowValue;
}
else
{
ctl.textBox1.Text = (String)this.Value;
}
} public override Type EditType
{
get
{
// Return the type of the editing control that CalendarCell uses.
return typeof(ScriptTextEditingControl);
}
} public override Type ValueType
{
get
{
// Return the type of the value that CalendarCell contains. return typeof(String);
}
} public override object DefaultNewRowValue
{
get
{
// Use the current date and time as the default value.
string code = @"
#region
//jackwangcumt
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Host_Controls_in_Windows_Forms_DataGridView_Cells
{
public partial class SourceTextBox : UserControl
{
public SourceTextBox()
{
InitializeComponent();
this.textBox1.Location = this.Location;
this.textBox1.Width = this.Width;
this.textBox1.Height = this.Height;
}
protected void OnValueChanged(string text)
{
this.textBox1.Text = text;
} private void btnSource_Click(object sender, EventArgs e)
{
ScriptEditor frm = new ScriptEditor(this.textBox1.Text);
frm.ShowDialog();
this.textBox1.Text = frm.fastColoredTextBox1.Text;
}
}
}
";
return code;
}
}
}
//----------------------------------------------------------------- class ScriptTextEditingControl : SourceTextBox, IDataGridViewEditingControl
{
DataGridView dataGridView;
private bool valueChanged = false;
int rowIndex; public ScriptTextEditingControl()
{
//文本变更更新到cell
this.textBox1.TextChanged += new EventHandler(textBox1_TextChanged);
} void textBox1_TextChanged(object sender, EventArgs e)
{
// Notify the DataGridView that the contents of the cell
// have changed.
valueChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
//调用SourceTextBox的OnValueChanged(string Text)
base.OnValueChanged(this.textBox1.Text);
} // Implements the IDataGridViewEditingControl.EditingControlFormattedValue
// property.
public object EditingControlFormattedValue
{
get
{
return this.textBox1.Text;
}
set
{
if (value is String)
{
try
{
// This will throw an exception of the string is
// null, empty, or not in the format of a date.
this.textBox1.Text=((String)value);
}
catch
{
// In the case of an exception, just use the
// default value so we're not left with a null
// value.
this.textBox1.Text = "jackwangcumt>>error";
}
}
}
} // Implements the
// IDataGridViewEditingControl.GetEditingControlFormattedValue method.
public object GetEditingControlFormattedValue(
DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
} // Implements the
// IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
public void ApplyCellStyleToEditingControl(
DataGridViewCellStyle dataGridViewCellStyle)
{
this.Font = dataGridViewCellStyle.Font;
//this.CalendarForeColor = dataGridViewCellStyle.ForeColor;
//this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;
} // Implements the IDataGridViewEditingControl.EditingControlRowIndex
// property.
public int EditingControlRowIndex
{
get
{
return rowIndex;
}
set
{
rowIndex = value;
}
} // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey
// method.
public bool EditingControlWantsInputKey(
Keys key, bool dataGridViewWantsInputKey)
{
// Let the DateTimePicker handle the keys listed.
switch (key & Keys.KeyCode)
{
case Keys.Left:
case Keys.Up:
case Keys.Down:
case Keys.Right:
case Keys.Home:
case Keys.End:
case Keys.PageDown:
case Keys.PageUp:
return true;
default:
return !dataGridViewWantsInputKey;
}
} // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit
// method.
public void PrepareEditingControlForEdit(bool selectAll)
{
// No preparation needs to be done.
} // Implements the IDataGridViewEditingControl
// .RepositionEditingControlOnValueChange property.
public bool RepositionEditingControlOnValueChange
{
get
{
return false;
}
} // Implements the IDataGridViewEditingControl
// .EditingControlDataGridView property.
public DataGridView EditingControlDataGridView
{
get
{
return dataGridView;
}
set
{
dataGridView = value;
}
} // Implements the IDataGridViewEditingControl
// .EditingControlValueChanged property.
public bool EditingControlValueChanged
{
get
{
return valueChanged;
}
set
{
valueChanged = value;
}
} // Implements the IDataGridViewEditingControl
// .EditingPanelCursor property.
public Cursor EditingPanelCursor
{
get
{
return base.Cursor;
}
} protected override void OnTextChanged(EventArgs e)
{
// Notify the DataGridView that the contents of the cell
// have changed.
valueChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnTextChanged(e); } } }

2 SourceTextBox

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms; namespace Host_Controls_in_Windows_Forms_DataGridView_Cells
{
public partial class SourceTextBox : UserControl
{
public SourceTextBox()
{
InitializeComponent();
this.textBox1.Location = this.Location;
this.textBox1.Width = this.Width;
this.textBox1.Height = this.Height;
}
protected void OnValueChanged(string text)
{
this.textBox1.Text = text;
} private void btnSource_Click(object sender, EventArgs e)
{
ScriptEditor frm = new ScriptEditor(this.textBox1.Text);
frm.ShowDialog();
this.textBox1.Text = frm.fastColoredTextBox1.Text;
}
}
}
 namespace Host_Controls_in_Windows_Forms_DataGridView_Cells
{
partial class SourceTextBox
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region 组件设计器生成的代码 /// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.btnSource = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBox1.Location = new System.Drawing.Point(, );
this.textBox1.Margin = new System.Windows.Forms.Padding();
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(, );
this.textBox1.TabIndex = ;
//
// btnSource
//
this.btnSource.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Right)));
this.btnSource.BackColor = System.Drawing.Color.Transparent;
this.btnSource.BackgroundImage = global::Host_Controls_in_Windows_Forms_DataGridView_Cells.Resource.setting;
this.btnSource.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.btnSource.FlatAppearance.BorderColor = System.Drawing.Color.White;
this.btnSource.FlatAppearance.BorderSize = ;
this.btnSource.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnSource.Font = new System.Drawing.Font("新宋体", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)()));
this.btnSource.Location = new System.Drawing.Point(, -);
this.btnSource.Margin = new System.Windows.Forms.Padding();
this.btnSource.Name = "btnSource";
this.btnSource.Size = new System.Drawing.Size(, );
this.btnSource.TabIndex = ;
this.btnSource.UseVisualStyleBackColor = false;
this.btnSource.Click += new System.EventHandler(this.btnSource_Click);
//
// SourceTextBox
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.btnSource);
this.Controls.Add(this.textBox1);
this.Margin = new System.Windows.Forms.Padding();
this.Name = "SourceTextBox";
this.Size = new System.Drawing.Size(, );
this.ResumeLayout(false);
this.PerformLayout(); } #endregion public System.Windows.Forms.Button btnSource;
public System.Windows.Forms.TextBox textBox1;
}
}

3 效果

C#如何在DataGridViewCell中自定义脚本编辑器的更多相关文章

  1. 6.1 如何在spring中自定义xml标签

    dubbo自定义了很多xml标签,例如<dubbo:application>,那么这些自定义标签是怎么与spring结合起来的呢?我们先看一个简单的例子. 一 编写模型类 package ...

  2. 如何在 Azure 中自定义 Windows 虚拟机

    若要以快速一致的方式配置虚拟机 (VM),通常需要某种形式的自动化. 自定义 Windows VM 的一种常用方法是使用适用于 Windows 的自定义脚本扩展. 本教程介绍如何执行下列操作: 使用自 ...

  3. 如何在pyqt中自定义无边框窗口

    前言 之前写过很多关于无边框窗口并给窗口添加特效的博客,按照时间线罗列如下: 如何在pyqt中实现窗口磨砂效果 如何在pyqt中实现win10亚克力效果 如何在pyqt中通过调用SetWindowCo ...

  4. 如何在CODESOFT中自定义删除文档备料

    CODESOFT 2015是先进的标签设计与集成软件.在使用CODESOFT制作条码标签时,为方便省时,我们可以事先创建自己的文档模板,保存它们以供将来使用.接下来,小编就讲讲CODESOFT 201 ...

  5. [VBA]用一个简单例子说明如何在Excel中自定义函数

    Excel中的函数无疑是强大的,但是再强大的战士也有他脆弱的脚后跟[1].这两天在使用Excel的时候遇到了一个需求,要在某一个单元格里面自动计算今天是星期几(如显示 Today is Tuesday ...

  6. ASP.NET MVC如何在Action中返回脚本并执行

    我们都知道在aspx页面的cs文件中只要用Respos.Write("<script></scritp>")就可以在前台执行脚本 但是在MVC中就不一样了, ...

  7. 如何在C#中自定义自己的异常

    在C#中所有的异常类型都继承自System.Exception,也就是说,System.Exception是所有异常类的基类. 总起来说,其派生类分为两种:1. SystemException类: 所 ...

  8. 在 Symfony Command中自定义脚本把Excel数据导入到数据库中

    // 注:只是在此做下记录,有兴趣的可以参考,不做实际教程文档 <?php/** * Created by IntelliJ IDEA. * User: davis * Date: 2019-0 ...

  9. 如何在windows7中使用“专用字符编辑器”中的字

    工具/原料 win7电脑 系统自带的“专用字符编辑器” 系统自带的“字符映射表” 百度经验:jingyan.baidu.com 方法/步骤 1 点击开始→所有程序→附件→系统工具→专用字符编辑器: 步 ...

随机推荐

  1. 移动web开发之移动端真机测试

    × 目录 [1]特性 [2]安装 [3]设置[4]移动端 前面的话 chrome的开发者工具可以很好地做好模拟工作,但毕竟模拟和实际还是有差别的.所以,真机测试是一定要做的,如何高效地进行真机测试呢. ...

  2. java中变量运算细节 (2)

    /* 目的:测试变量的运算方式 结果:byte a, b, c; a = b+c; 或者 a = b+10 形如这种形式的算式, 等式的右边的运算结果默认的都是int型的!因为等式右边有变量, 编译器 ...

  3. maven -- 学习笔记(四)实现在Eclipse用maven搭建springmvc项目(附构建步骤和详细实现代码)

    Learn from:http://www.cnblogs.com/fangjins/archive/2012/05/06/2485459.html,感谢楼主的分享,才有下面的这篇学习小结 一.环境准 ...

  4. JavaScript禁用页面刷新

    JavaScript禁用页面刷新代码如下: //禁用F5刷新 document.onkeydown = function () { if (event.keyCode == 116) { event. ...

  5. Javascript定时器(一)——单线程

    一.JavaScript 引擎是单线程的 可以从下面的代码中看到,第一个用setTimeout中的代码是死循环,由于是单线程,下面的两个定时器就没机会执行了. <script type=&quo ...

  6. 推荐15款最好的 Twitter Bootstrap 开发工具

    Twitter Bootstrap 自从2011年最初发布到网上后,迅速成为 Web 领域最流行的响应式前端开发框架之一,是网页设计的优秀实践.Twitter Bootstrap 框架包含了众多的预定 ...

  7. Linux菜鸟级重点

    这是本人自学Linux所做的笔记,以及实现一些功能作的总结.乐意与各位喜欢linux的朋友交流学习,共同进步.这篇文章只是简单介绍一些linux比较常用的或者说是最基础的也是最重要的知识,有些在模块后 ...

  8. 自制Https证书并在Spring Boot和Nginx中使用

    白话Https一文中, 介绍了Https存在的目的和工作原理,但多是偏向于原理性的介绍,本文介绍如何一步一步自制一个能够通过浏览器认证的Https证书,并讲解在Spring Boot环境和Nginx环 ...

  9. Android聚合广告AFP的对接系统设计

    工作需要,要对接阿里妈妈的广告聚合平台,简称AFP.对于一般的应用而言,想要流量变现,广告是显而易见的手段,尤其是在中国,打开一个千万级别的用户,肯定有某个地方是有对接广告的,只不过明不明显而已. 阿 ...

  10. 一篇学习HTTP状态码的神文:我与依依的橙色岁月

    好的,事情是这样的,数年前,我曾有过一段美好的夏日恋情,在此与大家分享. 依依 这个女孩叫做依依 ,她是 80 后的,生日是 1989 年 3 月吧,忘了哪一天了,分手太久了,记不起来了. 转学生 我 ...