最近一个需求是好友张作涛的创意,实现类似Word域功能的RichTextBox,以实现自定义模版功能。域是Word中最具有实用价值的功能之一,它表示文档中可能发生变化的数据或邮件合并文档中套用信函、标签中的占位符。在我们实现的RTF版本中,将域定义为一个封闭的字符串,并将这个具有域的RTF内容称之为"模板"。


我们的具体需求为:
1、自定义一个模拟Word域的封闭字符串,即域占位符,我们简单的将占位符定义为[...];
2、允许从外部拖动一个代表域的控件到RichTextBox中,自动生成域占位符;
3、在RTF格式化的文本中查找这个域占位符;
4、允许从SQL Server数据库中存取具有域的RTF内容;
5、将域与相应数据库表的字段关联起来,用字段值替换域占位符;
首先,RTF编码中可能含有单引号,而我们又不得不使用SQL Server 2008,这时就出现了数据库字段值的单引号问题。在我们的版本中使用加密字符串对此来进行处理,最大限度避免单引号问题。
加密方法的定义如下,具体方法的内容详见附带源码:
private string Decrypt(String strText, String sDecrKey)
public string Encrypt(string stringToEncrypt, string SEncryptionKey)
定义两个数据库表Table1和Table2,分别保存域对应的值和RTF编码,数据库结构详见附带源码中的数据库备份,大致如下:
Table1的字段:
name nchar
sex nchar
age nchar
Table2的字段:
rtf ntext
plaintext ntext
保存rtf编码的代码如下:
//获取rtf
private void button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection conn = new SqlConnection(textBox1.Text);
SqlCommand sqlcmd = new SqlCommand();
sqlcmd.Connection = conn;
conn.Open();
sqlcmd.CommandText = "select top 1 * from table2";
SqlDataAdapter dbDA = new SqlDataAdapter();
dbDA.SelectCommand = sqlcmd;
DataSet ds = new DataSet();
dbDA.Fill(ds);
richTextBox1.Rtf = Decrypt(ds.Tables[0].Rows[0]["rtf"].ToString(), "&%#@?,:*");
}
catch //(Exception e)
{}
finally
{}
}
//保存rtf and plaintext
private void button4_Click(object sender, EventArgs e)
{
try
{
SqlConnection conn = new SqlConnection(textBox1.Text);
SqlCommand sqlcmd = new SqlCommand();
sqlcmd.Connection = conn;
conn.Open();
sqlcmd.CommandText = "select top 1 * from table2";
SqlDataAdapter dbDA = new SqlDataAdapter();
SqlParameter bjSqlParameter = new SqlParameter();
SqlCommand updateCommand = new SqlCommand("UPDATE table2 SET rtf = @rtf, plaintxt = @plaintxt", conn);
dbDA.UpdateCommand =updateCommand;
objSqlParameter = updateCommand.Parameters.Add("@rtf", SqlDbType.NText, 1000, "rtf");
objSqlParameter.SourceColumn = "rtf";
objSqlParameter.SourceVersion = DataRowVersion.Current;
bjSqlParameter = updateCommand.Parameters.Add("@plaintxt", SqlDbType.NText, 1000, "plaintxt");
objSqlParameter.SourceColumn = "plaintxt";
objSqlParameter.SourceVersion = DataRowVersion.Current;
dbDA.SelectCommand = sqlcmd;
DataSet ds = new DataSet();
dbDA.Fill(ds,"rtftable");
DataTable dbTable = ds.Tables[0];
DataRow dbRow = dbTable.Rows[0];
dbRow["rtf"] = Encrypt(richTextBox1.Rtf.ToString(), "&%#@?,:*");
dbRow["plaintxt"] = richTextBox1.Text;
dbDA.Update(ds, "rtftable");
}
catch //(Exception e)
{ }
finally
{ }
}
将控件拖动到RichtextBox中的实现在.Net下也是相当的简单,只要对待拖动的控件的MouseDown事件进行处理并传递需要的字符串即可:
private void button2_MouseDown(object sender, MouseEventArgs e)
{
button2.DoDragDrop(button2.Tag.ToString(), DragDropEffects.All);
}
RichTextBox控件自身具备接受拖动字符串的功能,所以不必专为RichTextBox创建接受拖动的处理。具体请详见博文附带源码。
该示例在 Windows XP SP3 + Visual Studio 2008 SP1 + SQL Server 2008 下编译调试成功。
【文章附带源码下载页面】
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14325734/viewspace-594634/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/14325734/viewspace-594634/