利用C#及RichTextBox简单实现Word域功能

最近一个需求是好友的创意,实现类似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 下编译调试成功。

利用C#及RichTextBox简单实现Word域功能

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

滚动到顶部