我有一个用于简单聊天的RichTextBox
,我可以在其中以编程方式添加行。
我将用户名设置为粗体,并将消息设置为常规样式。
在几行之后,我想删除第一行,以使聊天保持在可接受的长度。但是,当我这样做时,我会丢失文本格式,并且所有内容都显示为粗体。我做错了什么以及如何解决这个问题?
编辑
我可以解决无法删除第一行的问题。 我必须将 ReadOnly 属性设置为 false。尽管我能够添加新行,但它阻止了删除行。所以下面的代码可以删除行。感谢@TaW!
if (ChatText.Lines.Length >= 10)
{
int p = 0; int count = 0;
do
{
p = ChatText.Text.IndexOf("\n\r");
if (p >= 0)
{
ChatText.SelectionStart = p;
ChatText.SelectionLength = 2; // length of "\n\r"
ChatText.SelectedText = "\n";
count++;
}
}
while(p >= 0);
int nll = 1; // <<=== pick the length of your new line character(s)!!
int pS = ChatText.Lines.Take(0).Select(x => x.Length + nll).Sum() - nll;
int pL = ChatText.Lines.Take(1).Select(x => x.Length + nll).Sum() - nll;
if (pS < 0) { pS = 0; pL++; }
ChatText.SelectionStart = pS;
ChatText.SelectionLength = pL - pS;
ChatText.Cut();
}
//////////////////////////////////
// now add new lines
//////////////////////////////////
string[] chatstr;
// string text is given as method parameter
chatstr = text.Split(new string[] { ": " }, 2, StringSplitOptions.None);
// go to the end of the text
ChatText.SelectionStart = ChatText.Text.Length;
ChatText.SelectionLength = 0;
// make text bold
ChatText.SelectionFont = new Font(ChatText.Font, FontStyle.Bold);
// add username (chatstr[0]) and colon
ChatText.AppendText(chatstr[0] + ": ");
// make text regular
ChatText.SelectionFont = new Font(ChatText.Font, FontStyle.Regular);
// add message (chatstr[1])
ChatText.AppendText(chatstr[1] + "\n");
// and finaly scroll down
ChatText.ScrollToCaret();
因此,删除行有效,并且新行会按预期添加。终于!
已解决:)
最佳答案
切勿更改 RichtTextBox
的文本
(如果它包含任何格式)。
更改Lines
属性(通过Skip
)只是更改Text
的另一种方法。
相反,仅使用 RTB 提供的功能:始终首先选择要格式化的部分,然后应用一个或多个功能和/或设置一个或更多属性..:
要删除部分,请使用剪切
。
这是一个将删除多个整行的函数:
void DeleteLines(RichTextBox rtb, int fromLine, int count)
{
int p1 = rtb.GetFirstCharIndexFromLine(fromLine);
int p2 = rtb.GetFirstCharIndexFromLine(fromLine + count);
rtb.SelectionStart = p1;
rtb.SelectionLength = p2 - p1;
bool readOnly = rtb.ReadOnly; // allow change even when the RTB is readonly
rtb.ReadOnly = false; ;
rtb.Cut();
rtb.ReadOnly = readOnly;
}
尝试自己保持格式是一种乏味且容易出错的浪费时间。
除了字体属性之外,您还必须重新存储可以使用 SelectedXXX
属性设置的所有其他内容,例如颜色、对齐方式、间距等。
要删除前 3 行,请使用:
DeleteLines(yourRTB, 0, 3);
要将文本限制为 10 行,请使用:
DeleteLines(yourRTB, 0, yourRTB.Lines.Length - 10);
请注意,上面的函数应该对有效输入进行一些检查;我将它们排除在外,因为检查在某种程度上需要决定要做什么,如果 count
或 fromLine
如果大于 Lines.Length
或如果 fromLine
为负数..
当我们这样做时,以下是如何附加粗线:
yourRTB.SelectionStart = yourRTB.Text.Length;
yourRTB.SelectionLength = 0;
using (Font font = new Font(yourRTB.SelectionFont, FontStyle.Bold))
yourRTB.SelectionFont = font;
yourRTB.AppendText(yourNewLine + textOfNewLine);
当然,它确实应该进入一个可重用的函数,以粗体作为参数。
更新:
由于您使用的是WordWrap
,您可能更喜欢此功能。它删除实际的行,而不是可见的行:
void DeleteLinesWW(RichTextBox rtb, int fromLine, int count)
{
int nll = 1; // <<=== pick the length of your new line character(s)!!
int pS = rtb.Lines.Take(fromLine).Select(x => x.Length + nll).Sum() - nll;
int pL = rtb.Lines.Take(fromLine + count).Select(x => x.Length + nll).Sum() - nll;
if (pS < 0) { pS = 0; pL++; }
rtb.SelectionStart = pS;
rtb.SelectionLength = pL - pS ;
bool readOnly = rtb.ReadOnly;
rtb.ReadOnly = false; // allow change even when the RTB is readonly
rtb.Cut();
rtb.ReadOnly = readOnly;
}
关于 NewLine 的一句话:请注意,我没有使用过 Environment.NewLine
常量,因为它并不是一个很好的选择。想法。如果您将多行文本添加到设计器中的 RichTextBox
中,然后查看它,您会发现它使用简单的 '\n' 换行符,没有回车,没有 NL-CR,只是 '\n' 。所以这似乎是 winforms RTB 中的通用方式,我建议使用它..
新函数依赖于所有具有相同长度换行符的行!
为了确保您可以使用此替换功能:
int RTBReplace(RichTextBox rtb, string oldText, string newText)
{
int p = 0; int count = 0;
do
{
p = richTextBox1.Text.IndexOf(oldText);
if (p >= 0)
{
richTextBox1.SelectionStart = p;
richTextBox1.SelectionLength = oldText.Length;
richTextBox1.SelectedText = newText;
count ++;
}
}
while (p >= 0);
return count;
}
这样调用它:
RTBReplace(yourrichTextBox, "\r\n", "\n");
更新2:
以下是如何添加聊天行的示例:
private void button1_Click(object sender, EventArgs e)
{
string cLine = "Taw: Hello World"; // use your own lines!
var chatstr = cLine.Split(new string[] { ": " }, 2, StringSplitOptions.None);
AppendLineBold(yourrichTextBox, "\n" + chatstr[0], true);
AppendLineBold(yourrichTextBox, chatstr[1], false);
yourrichTextBox.ScrollToCaret();
}
void AppendLineBold(RichTextBox rtb, string text, bool bold)
{
rtb.SelectionStart = richTextBox1.Text.Length;
rtb.SelectionLength = 0;
using (Font font = new Font(rtb.SelectionFont,
bold ? FontStyle.Bold : FontStyle.Regular))
rtb.SelectionFont = font;
rtb.AppendText(text);
}
更新3:
看起来ReadOnly
属性不允许使用Cut
。因此我们需要暂时允许更改。
有趣:SelectedText
也无法设置,但 AppendText
工作正常..
关于C# 删除行后在 RichTextBox 中丢失字体样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36950939/