在 RichTextBox 中使用之前,将 XML 中的格式属性添加到文本
Add formatting attributes from XML to text prior to use in a RichTextBox
我的 XML 文件存储文本段落并具有定义段落类型的属性。
例如:
<Content>
<Paragraph Type="Period">
<Text>A long long time ago</Text>
</Paragraph>
<Paragraph Type="location">
<Text>in a galaxy far, far away</Text>
</Paragraph>
<Paragraph Type="GeneralText">
<Text>It is a period of civil war. Rebel spaceships, striking from a hidden base, ... Pursued by the Empire’s sinister agents, Princess Leia races home aboard her starship, custodian of the stolen plans that can save her people and restore freedom to the galaxy….</Text>
</Paragraph>
<Paragraph Type="location">
<Text>And here's another location</Text>
</Paragraph>
</Content>
我正在寻找一种方法,当文本显示在 RichTextBox 中时向其添加某些属性。
例如,段落类型:
Period
,文本应具有黄色前景色、红色背景色、10
缩进和 20
右缩进。
GeneralText
,应该根本就没有格式化。
Location
,它也可以有不同的格式,棕色、橙色、居中等等!
我知道如何遍历 XML 和如何检索 XML 属性以及如何将每个段落附加到 RichTextBox,但如何添加这些格式属性?
一些可以帮助您入门的建议。
▶ 使用 class 对象来保存您的 XML 描述符可能需要的所有属性
▶ 预先构建这些对象的列表,这些对象在首次构建应用程序时已知,可以选择在设计时和 运行 时编辑它们的属性,以进行自定义。
▶ 提供添加更多这些描述符的方法:
- 动态 - 在加载 XML 文件时读取类型的 XML 属性
- 交互式 - 使用 PropertyGrid 将元素添加到段落描述符集合中
- 以编程方式 - 允许在 运行-Time 请求时使用自定义界面添加元素。
您还可以拥有保存新描述符对象的代码(序列化到光盘、添加到用户设置等)
在示例中,自定义控件 - 从 RichTextBox 派生 - 包含从已知模式加载 XML 数据所需的所有逻辑,分配段落类型描述符(使用 class 对象, XmlDescriptor
,每读一段)。
使用此信息,将文本发送到 RichTextBox 容器,使用指定的参数格式化新的 Selection。
请注意,XmlDescriptor
对象的集合是通过 ParagraphsDescriptors
属性 公开的。可以使用 PropertyGrid 编辑此集合:您可以修改现有描述符或添加新描述符。
如果更改描述符集合,请重新加载 XML 以查看应用的更改。
使用自定义 RichTextBox LoadXml()
方法(传递一个 XML 字符串或重载该方法以同时传递文件路径)加载XML 并应用样式。
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Xml.Linq
<DesignerCategory("Code")>
Public Class RichTextBoxEx
Inherits RichTextBox
Private m_xmlContent As String = String.Empty
Public Sub New()
Me.ParagraphsDescriptors = New List(Of XmlDescriptor)({
New XmlDescriptor("Period", HorizontalAlignment.Left, Color.Red, Color.LightYellow, 10, 20),
New XmlDescriptor("Location", HorizontalAlignment.Center, Color.Brown, Color.Orange, 5, 0),
New XmlDescriptor("GeneralText", HorizontalAlignment.Left, Color.White, Color.Black, 0, 0)
})
End Sub
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public Property ParagraphsDescriptors As List(Of XmlDescriptor)
Public ReadOnly Property XmlContent As String
Get
Return m_xmlContent
End Get
End Property
Public Function LoadXml(xml As String, Optional append As Boolean = False) As Boolean
If (String.IsNullOrEmpty(xml)) Then Return False
Try
Dim xElm As XElement = XElement.Parse(xml)
m_xmlContent = xml
If (Not append) Then Me.Clear()
For Each node As XElement In xElm.Elements.Where(Function(n) n.Name.LocalName.Equals("Paragraph"))
Dim txt = node.Elements.FirstOrDefault(Function(elm) elm.Name.LocalName.Equals("Text"))
If txt IsNot Nothing Then
AddParagraph(node.Attributes, txt.Value)
End If
Next
Return True
Catch ex As Exception
MessageBox.Show($"LoadXml failed: {ex.Message}")
Return False
End Try
End Function
Public Sub AddParagraph(attributes As IEnumerable(Of XAttribute), text As String)
Dim paragraphType = attributes.FirstOrDefault(Function(a) a.Name.LocalName.Equals("Type"))?.Value
If String.IsNullOrEmpty(paragraphType) Then Throw New ArgumentException("ParagraphType")
' Parse the other Attributes, eventually, to map them to XmlDescriptor properties
Dim descriptor = ParagraphsDescriptors.FirstOrDefault(Function(d) d.ParagraphType.Equals(paragraphType))
If descriptor Is Nothing Then descriptor = New XmlDescriptor(paragraphType)
Dim selStart = Me.TextLength
Me.AppendText(text + ChrW(10))
Me.Select(selStart, text.Length)
Me.SelectionAlignment = descriptor.Alignment
Me.SelectionIndent = descriptor.LeftIndent
Me.SelectionRightIndent = descriptor.RightIndent
Me.SelectionBackColor = descriptor.BackColor
Me.SelectionColor = descriptor.ForeColor
End Sub
<TypeConverter(GetType(ExpandableObjectConverter))>
Public Class XmlDescriptor
Public Sub New()
End Sub
Public Sub New(parName As String)
ParagraphType = parName
End Sub
Public Sub New(parName As String, textAlign As HorizontalAlignment, bkColor As Color, textColor As Color, indentLeft As Integer, indentRight As Integer)
ParagraphType = parName
Alignment = textAlign
BackColor = bkColor
ForeColor = textColor
LeftIndent = indentLeft
RightIndent = indentRight
End Sub
Public Property ParagraphType As String = String.Empty
Public Property Alignment As HorizontalAlignment = HorizontalAlignment.Left
Public Property BackColor As Color = SystemColors.Window
Public Property ForeColor As Color = SystemColors.ControlText
Public Property LeftIndent As Integer = 0
Public Property RightIndent As Integer = 0
End Class
End Class
我的 XML 文件存储文本段落并具有定义段落类型的属性。
例如:
<Content>
<Paragraph Type="Period">
<Text>A long long time ago</Text>
</Paragraph>
<Paragraph Type="location">
<Text>in a galaxy far, far away</Text>
</Paragraph>
<Paragraph Type="GeneralText">
<Text>It is a period of civil war. Rebel spaceships, striking from a hidden base, ... Pursued by the Empire’s sinister agents, Princess Leia races home aboard her starship, custodian of the stolen plans that can save her people and restore freedom to the galaxy….</Text>
</Paragraph>
<Paragraph Type="location">
<Text>And here's another location</Text>
</Paragraph>
</Content>
我正在寻找一种方法,当文本显示在 RichTextBox 中时向其添加某些属性。
例如,段落类型:
Period
,文本应具有黄色前景色、红色背景色、10
缩进和20
右缩进。GeneralText
,应该根本就没有格式化。Location
,它也可以有不同的格式,棕色、橙色、居中等等!
我知道如何遍历 XML 和如何检索 XML 属性以及如何将每个段落附加到 RichTextBox,但如何添加这些格式属性?
一些可以帮助您入门的建议。
▶ 使用 class 对象来保存您的 XML 描述符可能需要的所有属性
▶ 预先构建这些对象的列表,这些对象在首次构建应用程序时已知,可以选择在设计时和 运行 时编辑它们的属性,以进行自定义。
▶ 提供添加更多这些描述符的方法:
- 动态 - 在加载 XML 文件时读取类型的 XML 属性
- 交互式 - 使用 PropertyGrid 将元素添加到段落描述符集合中
- 以编程方式 - 允许在 运行-Time 请求时使用自定义界面添加元素。
您还可以拥有保存新描述符对象的代码(序列化到光盘、添加到用户设置等)
在示例中,自定义控件 - 从 RichTextBox 派生 - 包含从已知模式加载 XML 数据所需的所有逻辑,分配段落类型描述符(使用 class 对象, XmlDescriptor
,每读一段)。
使用此信息,将文本发送到 RichTextBox 容器,使用指定的参数格式化新的 Selection。
请注意,XmlDescriptor
对象的集合是通过 ParagraphsDescriptors
属性 公开的。可以使用 PropertyGrid 编辑此集合:您可以修改现有描述符或添加新描述符。
如果更改描述符集合,请重新加载 XML 以查看应用的更改。
使用自定义 RichTextBox LoadXml()
方法(传递一个 XML 字符串或重载该方法以同时传递文件路径)加载XML 并应用样式。
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Xml.Linq
<DesignerCategory("Code")>
Public Class RichTextBoxEx
Inherits RichTextBox
Private m_xmlContent As String = String.Empty
Public Sub New()
Me.ParagraphsDescriptors = New List(Of XmlDescriptor)({
New XmlDescriptor("Period", HorizontalAlignment.Left, Color.Red, Color.LightYellow, 10, 20),
New XmlDescriptor("Location", HorizontalAlignment.Center, Color.Brown, Color.Orange, 5, 0),
New XmlDescriptor("GeneralText", HorizontalAlignment.Left, Color.White, Color.Black, 0, 0)
})
End Sub
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public Property ParagraphsDescriptors As List(Of XmlDescriptor)
Public ReadOnly Property XmlContent As String
Get
Return m_xmlContent
End Get
End Property
Public Function LoadXml(xml As String, Optional append As Boolean = False) As Boolean
If (String.IsNullOrEmpty(xml)) Then Return False
Try
Dim xElm As XElement = XElement.Parse(xml)
m_xmlContent = xml
If (Not append) Then Me.Clear()
For Each node As XElement In xElm.Elements.Where(Function(n) n.Name.LocalName.Equals("Paragraph"))
Dim txt = node.Elements.FirstOrDefault(Function(elm) elm.Name.LocalName.Equals("Text"))
If txt IsNot Nothing Then
AddParagraph(node.Attributes, txt.Value)
End If
Next
Return True
Catch ex As Exception
MessageBox.Show($"LoadXml failed: {ex.Message}")
Return False
End Try
End Function
Public Sub AddParagraph(attributes As IEnumerable(Of XAttribute), text As String)
Dim paragraphType = attributes.FirstOrDefault(Function(a) a.Name.LocalName.Equals("Type"))?.Value
If String.IsNullOrEmpty(paragraphType) Then Throw New ArgumentException("ParagraphType")
' Parse the other Attributes, eventually, to map them to XmlDescriptor properties
Dim descriptor = ParagraphsDescriptors.FirstOrDefault(Function(d) d.ParagraphType.Equals(paragraphType))
If descriptor Is Nothing Then descriptor = New XmlDescriptor(paragraphType)
Dim selStart = Me.TextLength
Me.AppendText(text + ChrW(10))
Me.Select(selStart, text.Length)
Me.SelectionAlignment = descriptor.Alignment
Me.SelectionIndent = descriptor.LeftIndent
Me.SelectionRightIndent = descriptor.RightIndent
Me.SelectionBackColor = descriptor.BackColor
Me.SelectionColor = descriptor.ForeColor
End Sub
<TypeConverter(GetType(ExpandableObjectConverter))>
Public Class XmlDescriptor
Public Sub New()
End Sub
Public Sub New(parName As String)
ParagraphType = parName
End Sub
Public Sub New(parName As String, textAlign As HorizontalAlignment, bkColor As Color, textColor As Color, indentLeft As Integer, indentRight As Integer)
ParagraphType = parName
Alignment = textAlign
BackColor = bkColor
ForeColor = textColor
LeftIndent = indentLeft
RightIndent = indentRight
End Sub
Public Property ParagraphType As String = String.Empty
Public Property Alignment As HorizontalAlignment = HorizontalAlignment.Left
Public Property BackColor As Color = SystemColors.Window
Public Property ForeColor As Color = SystemColors.ControlText
Public Property LeftIndent As Integer = 0
Public Property RightIndent As Integer = 0
End Class
End Class