如何在Telerik UI for WPF表格单元格中添加DocumentVariableField
在RadRichTextBox表格指定单元格中添加可持久化的DocumentVariableField
要解决在表格第一行第二列插入可同步更新且能在RTF中持久化的DocumentVariableField问题,核心是直接在构建单元格内容时将字段嵌入到目标段落中,而非依赖光标位置的InsertField方法(该方法会将字段插入到文档当前光标处,而非指定单元格)。以下是具体实现方案:
关键修改点
- 在构建第一行第二列单元格(cell2)时,移除原有的Span,转而创建DocumentVariableField并将其字段内容添加到段落中
- 确保先将变量添加到文档的
DocumentVariables集合,再构建字段内容 - 字段会随RTF格式原生保存,无需依赖无法持久化的Tag属性
修改后的AddAddress方法代码
public void AddAddress() { string addrName = " "; string[] rowName = new string[] { "Job Title", "Employer", "Address", "Tel.", "Tel. Dir.", "Mobile", "Email", "Website", "Fax", "Details", "Address", "Tel.", "Mobile", "Email", "Details" }; if(_selelement != null) { addrName = _selelement.GetAttribute("title"); } RadDocument document = new RadDocument(); Section section = new Section(); TableWidthUnit w1 = new TableWidthUnit(100); TableWidthUnit w2 = new TableWidthUnit(520); Table table = new Table(); table.StyleName = RadDocumentDefaultStyles.DefaultTableGridStyleName; TableRow row1 = new TableRow(); TableCell cell1 = new TableCell(); cell1.Background = Color.FromRgb(174, 255, 190); cell1.PreferredWidth = w1; cell1.Padding = new Telerik.Windows.Documents.Layout.Padding(3, 6, 3, 6); Paragraph p1 = new Paragraph(); Span s1 = new Span(); s1.FontWeight = FontWeights.Bold; s1.FontFamily = new FontFamily(CGlobals.docu_default_font); s1.FontSize = Unit.PointToDip(CGlobals.docu_default_font_size); s1.Text = "Name"; p1.Inlines.Add(s1); cell1.Blocks.Add(p1); row1.Cells.Add(cell1); TableCell cell2 = new TableCell(); cell2.Background = Color.FromRgb(174, 255, 190); cell2.PreferredWidth = w2; cell2.Padding = new Telerik.Windows.Documents.Layout.Padding(3, 6, 3, 6); Paragraph p2 = new Paragraph(); // --- 关键修改:替换Span为DocumentVariableField --- string variableName = "1001"; // 先将变量添加到文档的变量集合 document.DocumentVariables.Add(variableName, addrName); // 创建文档变量字段 DocumentVariableField docVariable = new DocumentVariableField { VariableName = variableName }; var fieldRangeStart = docVariable.CreateFieldRangeStart(); var fieldRangeEnd = new FieldRangeEnd { RangeStart = fieldRangeStart }; // 设置字段显示样式,与原Span保持一致 Span fieldSpan = new Span { FontWeight = FontWeights.Bold, FontFamily = new FontFamily(CGlobals.docu_default_font), FontSize = Unit.PointToDip(CGlobals.docu_default_font_size), Text = docVariable.GetResult() // 获取变量当前值作为显示内容 }; // 将字段元素依次添加到段落 p2.Inlines.Add(fieldRangeStart); p2.Inlines.Add(fieldSpan); p2.Inlines.Add(fieldRangeEnd); // --- 关键修改结束 --- cell2.Blocks.Add(p2); row1.Cells.Add(cell2); table.Rows.Add(row1); int rowCount = 0; foreach(string rname in rowName) { rowCount++; row1 = new TableRow(); cell1 = new TableCell(); p1 = new Paragraph(); if (rowCount < 11) { cell1.Background = Color.FromRgb(255, 229, 153); p1.Background = Color.FromRgb(255, 229, 153); } else { cell1.Background = Color.FromRgb(196, 255, 255); p1.Background = Color.FromRgb(196, 255, 255); } cell1.Padding = new Telerik.Windows.Documents.Layout.Padding(3, 6, 3, 6); s1 = new Span(); s1.FontWeight = FontWeights.Bold; s1.FontFamily = new FontFamily(CGlobals.docu_default_font); s1.FontSize = Unit.PointToDip(CGlobals.docu_default_font_size); s1.Text = rname; p1.Inlines.Add(s1); cell1.Blocks.Add(p1); row1.Cells.Add(cell1); cell2 = new TableCell(); cell2.Background = Color.FromRgb(255, 255, 255); cell2.Padding = new Telerik.Windows.Documents.Layout.Padding(3, 6, 3, 6); p2 = new Paragraph(); s2 = new Span(); s2.FontFamily = new FontFamily(CGlobals.docu_default_font); s2.FontSize = Unit.PointToDip(CGlobals.docu_default_font_size); s2.Text = " "; p2.Inlines.Add(s2); cell2.Blocks.Add(p2); row1.Cells.Add(cell2); table.Rows.Add(row1); } section.Blocks.Add(new Paragraph()); section.Blocks.Add(table); section.Blocks.Add(new Paragraph()); document.Sections.Add(section); doc_text.Document = document; // 移除原有的InsertField调用,字段已直接嵌入单元格 // doc_text.InsertField(docVariable, FieldDisplayMode.Result); // 可选:首次加载后触发更新确保显示正确 // ChangeAddress(addrName); }
原ChangeAddress方法说明
原ChangeAddress方法无需修改,可正常识别并更新目标字段:
public void ChangeAddress(string address) { doc_text.Document.DocumentVariables["1001"] = address; var field = doc_text.Document.EnumerateChildrenOfType<FieldRangeStart>() .Where(x => x.Field.FieldTypeName == "DOCVARIABLE" && ((DocumentVariableField)x.Field).VariableName == "1001") .FirstOrDefault(); if (field != null) { doc_text.UpdateField(field); } }
方案优势
- 字段直接归属目标单元格,彻底解决光标位置导致的插入错误问题
- DOCVARIABLE字段原生支持RTF持久化,保存后重新打开仍能识别并更新
- 完全保留原有的样式设置,字段显示效果与原Span一致
内容的提问来源于stack exchange,提问作者SteveP
相关产品推荐
相关产品推荐

