C#失去字体风格RichTextBox中删除行之后 [英] C# losing Font Style in RichTextBox after deleting lines

查看:147
本文介绍了C#失去字体风格RichTextBox中删除行之后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个的RichTextBox 为一个简单的聊天,我编程方式添加行。
我做用户名大胆在常规款式的消息。
部分线路我要删除的第一线,以保持聊天在一个可接受的长度后。但是,当我这样做,我失去了文本格式,一切都显得大胆。什么我做错了,我怎么能解决这个问题?



修改



我可以解决这个问题,我无法删除的第一行。
我不得不设置了只读属性设置为false。虽然我是能够增加新的生产线它阻止删除线。所以,下面的代码工作,以删除线。 !感谢@TaW

 如果(ChatText.Lines.Length> = 10)
{
INT p值= 0;诠释计数= 0;

{
P = ChatText.Text.IndexOf(\\\
\r);
如果(P> = 0)
{
ChatText.SelectionStart = P;
ChatText.SelectionLength = 2; //\\\
\r
ChatText.SelectedText =\\\
的长度;
计数++;
}
}
,而(P> = 0);

INT NLL = 1; //<< ===选择新的行字符(S)的长度!
INT PS = ChatText.Lines.Take(0)。选择(X => x.Length + NLL).SUM() - NLL;
INT PL = ChatText.Lines.Take(1)。选择(X => x.Length + NLL).SUM() - NLL;
如果(PS℃,){PS = 0; PL ++; }
ChatText.SelectionStart = PS;
ChatText.SelectionLength = PL - PS;
ChatText.Cut();
}
//////////////////////////////////
//现在添加新行
//////////////////////////////////
的String [] chatstr;
//字符串文本是作为方法参数
chatstr = text.Split(新的String [] {:},2,StringSplitOptions.None);
//转到文本
ChatText.SelectionStart = ChatText.Text.Length的结束;
ChatText.SelectionLength = 0;
//加粗文字
ChatText.SelectionFont =新字体(ChatText.Font,FontStyle.Bold);
//添加用户名(chatstr [0])和结肠
ChatText.AppendText(chatstr [0] +:);
//使文本定期
ChatText.SelectionFont =新字体(ChatText.Font,FontStyle.Regular);
//添加消息(chatstr [1])$ ​​B $ B ChatText.AppendText(chatstr [1] +\\\
);
//和finaly向下滚动
ChatText.ScrollToCaret();



所以,删除线工程和拟新行补充说。 Finaly



解决:!)


解决方案

从不修改的文本 A RichtTextBox 如果它包含的任何格式。



(由跳过)更改属性只是一个办法改变文本



而不是使用功能的RTB规定:务必通过选择部分开始,然后应用的一个或多个功能和/或设置属性的一个或多个..:



删除部分使用剪切



下面是将删除数的函数整个行:

 无效DeleteLines(RichTextBox的RTB,诠释fromLine,诠释计数)
{
INT P1 = rtb.GetFirstCharIndexFromLine(fromLine);
INT P2 = rtb.GetFirstCharIndexFromLine(fromLine +计数);

rtb.SelectionStart = P1;
rtb.SelectionLength = P2 - P1;

布尔readOnly的= rtb.ReadOnly; //允许改变甚至当RTB为只读
rtb.ReadOnly = FALSE; ;
rtb.Cut();
rtb.ReadOnly = readOnly的;
}



试图keept的格式化活着自己是一个繁琐且容易出错的浪费你的时间。



在除字体属性,你也必须resore所有其他的东西,你可以用 SelectedXXX 属性,例如颜色,对齐,间距等等等等。



要删除第3行是:

  DeleteLines(yourRTB,0,3); 

要限制文本10行,用:

  DeleteLines(yourRTB,0,yourRTB.Lines.Length  -  10); 

请注意,上面的函数应该有有效输入几个检查;我离开他们出来为检查是否以某种方式需要决定怎样做,如果计数 fromLine 大于 Lines.Length 或者 fromLine 为负..



虽然我们在这,这里是如何添加一个大胆的行:

  yourRTB.SelectionStart = yourRTB.Text.Length; 
yourRTB.SelectionLength = 0;
使用(字体的字体=新字体(yourRTB.SelectionFont,FontStyle.Bold))
yourRTB.SelectionFont =字体;
yourRTB.AppendText(yourNewLine + textOfNewLine);



当然它真的shold进入一个可重复使用的功能,该加粗的作为参数..



更新:



由于您使用的是自动换行你可能会喜欢这个功能。它删除的实际线,不可见的:

 无效DeleteLinesWW(RichTextBox的RTB,诠释fromLine,诠释计数)
{
INT NLL = 1; //<< ===选择新的行字符(S)的长度!
INT PS = rtb.Lines.Take(fromLine)。选择(X => x.Length + NLL).SUM() - NLL;
INT PL = rtb.Lines.Take(fromLine +计数)。选择(X => x.Length + NLL).SUM() - NLL;
如果(PS℃,){PS = 0; PL ++; }
rtb.SelectionStart = PS;
rtb.SelectionLength = PL - PS;

布尔readOnly的= rtb.ReadOnly;
rtb.ReadOnly = FALSE; //允许改变甚至当RTB为只读$ B($ B rtb.Cut);
rtb.ReadOnly = readOnly的;
}

在换行符一句:请注意,我有不可以使用了 Environment.NewLine 常数,因为它的不是一个真正的好主意。如果你在设计中添加多行文本到的RichTextBox 再看看它,你会看到它使用简单的'\\\
新的生产线,没有回报,没有NL- CR,只是'\\\
。因此,这似乎是一个WinForms RTB的通用方式,我建议使用它。



新的功能依赖于具有相同长度的新行所有行<! / p>

为确保您可以用这个替换功能:

  INT RTBReplace (RTB的RichTextBox,串oldText,串newText)
{
INT p = 0;诠释计数= 0;

{
P = richTextBox1.Text.IndexOf(oldText);
如果(P> = 0)
{
richTextBox1.SelectionStart = P;
richTextBox1.SelectionLength = oldText.Length;
richTextBox1.SelectedText = newText;
计数++;
}
}
,而(P> = 0);
返回计数;
}



调用它是这样的:

  RTBReplace(yourrichTextBox,\r\\\
,\\\
);



更新2:



下面是一个例子如何添加聊天行:

 私人无效的button1_Click(对象发件人,EventArgs五)
{
串克莱恩=Taw的:Hello World的; //使用自己的台词!
VAR chatstr = cLine.Split(新的String [] {:},2,StringSplitOptions.None);
AppendLineBold(yourrichTextBox\\\
+ chatstr [0],真);
AppendLineBold(yourrichTextBox,chatstr [1],假);
yourrichTextBox.ScrollToCaret();
}

无效AppendLineBold(RTB的RichTextBox,字符串文本,布尔粗体)
{
rtb.SelectionStart = richTextBox1.Text.Length;
rtb.SelectionLength = 0;
使用(字体的字体=新字体(rtb.SelectionFont,
大胆FontStyle.Bold:FontStyle.Regular))
rtb.SelectionFont =字体;
rtb.AppendText(文本);
}



更新3:



看起来像只读属性不允许使用剪切的。 。因此,我们需要temporatily允许更改



搞笑: SelectedText 也不能确定,但​​ AppendText通过工作正常..


I have a RichTextBox for a simple chat where I add lines programmatically. I make the usernames bold and the messages in regular style. After some lines I want to delete the first lines to keep the chat in a acceptably length. But when I do so I lose the text format and everything appears bold. What am I doing wrong and how can I fix this?

EDIT

I could solve the problem where I wasn't able to delete the first line. I had to set the the ReadOnly property to false. Even though I was able to add new lines it prevented deleting lines. So the following code works to delete lines. Thanks to @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();

So deleting lines works and new lines are added as intended. Finaly!

solved :)

解决方案

Never change the Text of a RichtTextBox if it contains any formatting.

Changing the Lines property (by Skip) is just another way to change the Text.

Instead only use the functions the RTB provides: Always start by selecting the portion, then apply one or more of the functions and/or set one or more of the properties..:

To delete portions use Cut.

Here is a function that will delete a number of entire lines:

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;
}

Trying to keept the formatting alive yourself is a tedious and error-prone waste of your time.

In addition to font properties you would also have to resore all other things you can set with the SelectedXXX properties, like colors, alignment, spacing etc etc..

To delete the first 3 lines use:

DeleteLines(yourRTB, 0, 3);

To restrict the text to 10 lines use:

DeleteLines(yourRTB, 0, yourRTB.Lines.Length - 10);

Note that the function above should have a few checks for valid input; I left them out as the checks somehow need a decision what to do, if count or fromLine if greater than Lines.Length or if fromLine is negative..

While we are at it, here is how to append a bold line:

yourRTB.SelectionStart = yourRTB.Text.Length;
yourRTB.SelectionLength = 0;
using (Font font = new Font(yourRTB.SelectionFont, FontStyle.Bold))
    yourRTB.SelectionFont = font;
yourRTB.AppendText(yourNewLine + textOfNewLine);

Of course it really shold go into a reuseable function that the the bolding as a parameter..

Update:

since you are using WordWrap you may prefer this function. It deletes the actual lines, not the visible ones:

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;  
  }

A word on NewLine: Do note that I have not used the Environment.NewLine constant as it not really a good idea. If you add multiline text to the RichTextBox in the designer and then look at it you will see that it uses simple '\n' new lines, no returns, no NL-CR, just '\n'. So this seems to be the generic way in a winforms RTB and I recommend using it..

The new function relies on all lines having a newline of the same length!

To make sure you can use this replacement function:

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;
}

Calling it like this:

RTBReplace(yourrichTextBox, "\r\n", "\n");

Update 2:

Here is an example how to add your chat lines:

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);
}

Update 3:

Looks like the ReadOnly property disallows the use of Cut. So we need to temporatily allow changes.

Funny: SelectedText can't be set either, but AppendText works fine..

这篇关于C#失去字体风格RichTextBox中删除行之后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆