更改任一元素时如何保持 RichText 格式(粗体/斜体/等)?
我有一个富文本框,其中可能包含一个包含粗体、斜体甚至不同字体和大小元素的字符串。如果我选择整个字符串,包括所有差异,如何“加粗”该字符串而不将整个字符串转换为仅具有“粗体”属性的通用字体?
例如:我想将“This is some text
”转换为“This is some text
” ”
请注意,“is some”仍然是斜体,“text”仍然是不同的字体。
我目前所拥有的非常简单:
private void tsBold_Click(object sender, EventArgs e)
{
if (rtb.SelectionFont == null) return;
Font f;
if (tsBold.Checked)
f = new Font(rtb.SelectionFont, FontStyle.Bold);
else
f = new Font(rtb.SelectionFont, FontStyle.Regular);
rtb.SelectionFont = f;
rtb.Focus();
}
当然,这会将完全相同的字体应用于整个选择。有什么方法可以将“粗体”附加到现有字体吗?
回答 虽然下面的“官方”答案只是冰山一角,但它是我需要朝正确方向前进的推动力。谢谢你的提示。
这是我的官方修复:
我将其添加到我的 RichTextBox 对象中:
/// <summary>
/// Change the richtextbox style for the current selection
/// </summary>
public void ChangeFontStyle(FontStyle style, bool add)
{
//This method should handle cases that occur when multiple fonts/styles are selected
// Parameters:-
// style - eg FontStyle.Bold
// add - IF true then add else remove
// throw error if style isn't: bold, italic, strikeout or underline
if (style != FontStyle.Bold
&& style != FontStyle.Italic
&& style != FontStyle.Strikeout
&& style != FontStyle.Underline)
throw new System.InvalidProgramException("Invalid style parameter to ChangeFontStyle");
int rtb1start = this.SelectionStart;
int len = this.SelectionLength;
int rtbTempStart = 0;
//if len <= 1 and there is a selection font then just handle and return
if (len <= 1 && this.SelectionFont != null)
{
//add or remove style
if (add)
this.SelectionFont = new Font(this.SelectionFont, this.SelectionFont.Style | style);
else
this.SelectionFont = new Font(this.SelectionFont, this.SelectionFont.Style & ~style);
return;
}
using (EnhancedRichTextBox rtbTemp = new EnhancedRichTextBox())
{
// Step through the selected text one char at a time
rtbTemp.Rtf = this.SelectedRtf;
for (int i = 0; i < len; ++i)
{
rtbTemp.Select(rtbTempStart + i, 1);
//add or remove style
if (add)
rtbTemp.SelectionFont = new Font(rtbTemp.SelectionFont, rtbTemp.SelectionFont.Style | style);
else
rtbTemp.SelectionFont = new Font(rtbTemp.SelectionFont, rtbTemp.SelectionFont.Style & ~style);
}
// Replace & reselect
rtbTemp.Select(rtbTempStart, len);
this.SelectedRtf = rtbTemp.SelectedRtf;
this.Select(rtb1start, len);
}
return;
}
然后我更改了单击方法以使用以下模式:
private void tsBold_Click(object sender, EventArgs e)
{
enhancedRichTextBox1.ChangeFontStyle(FontStyle.Bold, tsBold.Checked);
enhancedRichTextBox1.Focus();
}
I have a rich text box that may contain a string that has elements of bold, italics, or even different fonts and sizes. If I select the entire string, including all of the differences, how can I "Bold" that string without converting the entire string to the generic font with just a "bold" attribute?
For example: I want to turn "This is some text
" into "This is some text
"
Note that "is some" remained italicized and "text" remained a different font.
What I currently have is quite simplistic:
private void tsBold_Click(object sender, EventArgs e)
{
if (rtb.SelectionFont == null) return;
Font f;
if (tsBold.Checked)
f = new Font(rtb.SelectionFont, FontStyle.Bold);
else
f = new Font(rtb.SelectionFont, FontStyle.Regular);
rtb.SelectionFont = f;
rtb.Focus();
}
Of course, this is going to apply the exact same font to the entire selection. Is there any way to just append "bold" to the existing font(s)?
ANSWER
While the "official" answer below is just the tip of the iceberg, it was the push I needed in the right direction. Thank you for the tip.
Here's my official fix:
I added this to my RichTextBox object:
/// <summary>
/// Change the richtextbox style for the current selection
/// </summary>
public void ChangeFontStyle(FontStyle style, bool add)
{
//This method should handle cases that occur when multiple fonts/styles are selected
// Parameters:-
// style - eg FontStyle.Bold
// add - IF true then add else remove
// throw error if style isn't: bold, italic, strikeout or underline
if (style != FontStyle.Bold
&& style != FontStyle.Italic
&& style != FontStyle.Strikeout
&& style != FontStyle.Underline)
throw new System.InvalidProgramException("Invalid style parameter to ChangeFontStyle");
int rtb1start = this.SelectionStart;
int len = this.SelectionLength;
int rtbTempStart = 0;
//if len <= 1 and there is a selection font then just handle and return
if (len <= 1 && this.SelectionFont != null)
{
//add or remove style
if (add)
this.SelectionFont = new Font(this.SelectionFont, this.SelectionFont.Style | style);
else
this.SelectionFont = new Font(this.SelectionFont, this.SelectionFont.Style & ~style);
return;
}
using (EnhancedRichTextBox rtbTemp = new EnhancedRichTextBox())
{
// Step through the selected text one char at a time
rtbTemp.Rtf = this.SelectedRtf;
for (int i = 0; i < len; ++i)
{
rtbTemp.Select(rtbTempStart + i, 1);
//add or remove style
if (add)
rtbTemp.SelectionFont = new Font(rtbTemp.SelectionFont, rtbTemp.SelectionFont.Style | style);
else
rtbTemp.SelectionFont = new Font(rtbTemp.SelectionFont, rtbTemp.SelectionFont.Style & ~style);
}
// Replace & reselect
rtbTemp.Select(rtbTempStart, len);
this.SelectedRtf = rtbTemp.SelectedRtf;
this.Select(rtb1start, len);
}
return;
}
I then changed the click methods to use the following pattern:
private void tsBold_Click(object sender, EventArgs e)
{
enhancedRichTextBox1.ChangeFontStyle(FontStyle.Bold, tsBold.Checked);
enhancedRichTextBox1.Focus();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
RTB 对此的支持不太。您甚至无法发现所选内容中具有相同字体样式的字符范围。首先检查 SelectionFont 属性,如果选择包含混合样式,则该属性将为 null。如果是这种情况,您必须通过设置 SelectionStart 和 SelectionLength 属性一次迭代一个字符,读取 SelectionFont 直到它发生变化。将更改后的字体应用到您发现的范围。
检查这个答案寻找方法以保持相当快且无闪烁。
请注意,使用 RTB 实现编辑器是 codeproject.com 上最受欢迎的主题。借用代码(即使不是整个项目)也是减轻痛苦的好方法。
RTB does not support this well. You cannot even discover the range of characters within the selection that has the same font style. Start by checking the SelectionFont property first, it will be null if the selection contains a mix of styles. If that's the case, you'll have to iterate the selection one character at a time by setting the SelectionStart and SelectionLength properties, read the SelectionFont until it changes. Apply the changed font to the range you discovered.
Check this answer for a way to keep this reasonably quick and flicker-free.
Note that implementing an editor with RTB is a favorite topic at codeproject.com. Borrowing code, if not the entire project, is a good way to lessen the pain.
要使文本选择变为粗体,同时保持其格式完整,请使用以下命令:
要在保持其格式完整的同时取消粗体文本选择,请使用此命令:
请注意,上述代码仅在所有选定文本具有相同格式(字体大小、样式等)时才有效)。这是通过首先检查 SelectionFont 属性来检测的,如果选择包含混合样式,则该属性将为 null。
现在要对 RichTextBox 中的所有文本执行此操作,
现在要将 RichTextBox 的整个文本加粗/取消加粗,同时保持其他格式不变,您需要循环遍历 RichTextBox 的所有字符并一一应用加粗/取消加粗。这是完整的代码:
如果您需要切换粗体的现有状态(即使非粗体文本变为粗体并使粗体文本变为非粗体),请改用以下代码:
To make a text selection bold while keeping its formatting intact, use this:
To unBold text selection while keeping its formatting intact, use this:
Note that above code will only work, if all the selected text has same formatting (font size, style etc). This is detected by checking the SelectionFont property first, it will be null if the selection contains a mix of styles.
Now to do this with all text in richtextbox,
Now to Bold/unBold the entire text of richtextbox while keeping other formatting intact, you need to loop through all the characters of the richtextbox and apply Bold/unBold one by one. Here is the complete code:
If you need to toggle the existing state of Bold (i.e. make non-bold text Bold and make bold text unBold), use this instead:
如果您还想更改其字体系列和字体大小,您可以使用此方法:
汉斯是对的,你必须迭代每个字符。
有关更多说明,您可以访问: http://how-to-code-net.blogspot.ro/2014/01/how-to-make-custom-richtextbox-control.html
In case you want also to change its font family and font size you could use this method:
Hans is right, you have to iterate each character.
For more explanations you could go to: http://how-to-code-net.blogspot.ro/2014/01/how-to-make-custom-richtextbox-control.html
我还没有根据消耗更多内存的字体对象引用来测试它,但这
应该可以工作
I am yet to test it in terms of Font object references consuming more memory however
This should work
如果您想在同一文本上应用更多 FontStyle,您可以使用按位运算符 |和〜
|添加新样式并删除现有样式
例如
if you want to apply more FontStyle's on the same text you can use bitwise operators | and ~
| adds a new style and ~ removes an existing style
for example