c# - 在 RichTextBox 中插入笑脸会插入一些而忽略其他

c# - inserting smileys in RichTextBox inserts some and ignores others

我有一个代码可以将 richtextbox 中的符号替换为笑脸符号,这是代码:

private void add_smileys(RichTextBox addin)
        {
            try
            {
                while (addin.Text.Contains(":)"))
                {
                    addin.SelectionStart = addin.Find(":)", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_smile;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(">:("))
                {
                    addin.SelectionStart = addin.Find(">:(", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 3;

                    Image img = Resources.in_angry;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":D"))
                {
                    addin.SelectionStart = addin.Find(":D", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_lol;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":'("))
                {
                    addin.SelectionStart = addin.Find(":'(", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 3;

                    Image img = Resources.in_cry;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":("))
                {
                    addin.SelectionStart = addin.Find(":(", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_sad;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(";)"))
                {
                    addin.SelectionStart = addin.Find(";)", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_wink;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains("xD"))
                {
                    addin.SelectionStart = addin.Find("xD", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_laugh;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":P"))
                {
                    addin.SelectionStart = addin.Find(":P", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_tongue;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":|"))
                {
                    addin.SelectionStart = addin.Find(":|", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_neutral;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains("^^"))
                {
                    addin.SelectionStart = addin.Find("^^", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_happy;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains("o.O"))
                {
                    addin.SelectionStart = addin.Find("o.O", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 3;

                    Image img = Resources.in_dizzy;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":S"))
                {
                    addin.SelectionStart = addin.Find(":S", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_confused;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
                while (addin.Text.Contains(":O"))
                {
                    addin.SelectionStart = addin.Find(":O", RichTextBoxFinds.WholeWord);
                    addin.SelectionLength = 2;

                    Image img = Resources.in_omg;
                    Clipboard.SetImage(img);
                    addin.Paste();
                }
            }
            catch (Exception e)
            {
              MessageBox.Show(e.Message);
            }
        }

这是输出:

如您所见,有些符号被替换为笑脸符号,有些则没有。此外,我得到这个例外:

这个错误的原因是什么?我该如何解决?

I get this exception: enter image description here

What is the cause of this error? and how do I fix it?

Find 方法 returns -1 当要查找的字符串不存在时。此值对 addin.SelectionStart.

无效

您应该首先检查以确保 Find 方法的结果大于 -1 方法,然后再尝试使用该值。

var selectionStart = addin.Find(":)", RichTextBoxFinds.WholeWord);
if (selectionStart > -1)
{
    addin.SelectionStart = selectionStart;
    addin.SelectionLength = 2;
}

并且您的 Contains 和 Find 检查是多余的。出于某种原因,当您到达“^^”时,它们会返回不同的结果,这就是您收到错误的原因。但是要删除冗余,您应该在循环中使用 Find 方法而不是 Contains.

while (true)
{
    var selectionStart = addin.Find(":)", RichTextBoxFinds.WholeWord);
    if (selectionStart > -1)
    {
        addin.SelectionStart = selectionStart;
        addin.SelectionLength = 2;
    }
    else
    {
        break;
    }
}

我也觉得你的做法不是很干净。您可以使用 Dictionary<string, Image> 以更简单、更易于维护的方式完成所有替换。您还应该使用 @ 符号来转义字符串。

private void add_smileys(RichTextBox addin)
{
    var smileys = new Dictionary<string, Image>()
    {
        { @":)", Resources.in_smile },
        { @">:(", Resources.in_angry },
        { @":D", Resources.in_lol },
        { @":'(", Resources.in_cry },
        { @":(", Resources.in_sad },
        { @";)", Resources.in_wink },
        { @"xD", Resources.in_laugh },
        { @":P", Resources.in_tongue },
        { @":|", Resources.in_neutral },
        { @"^^", Resources.in_happy },
        { @"o.O", Resources.in_dizzy },
        { @":S", Resources.in_confused },
        { @":O", Resources.in_omg },
    };

    foreach (var smiley in smileys)
    {
        add_smiley(addin, smiley.Key, smiley.Value);
    }
}

private void add_smiley(RichTextBox addin, string token, Image smiley)
{
    while (true)
    {
        var selectionStart = addin.Find(token, RichTextBoxFinds.WholeWord);
        if (selectionStart < 0) break;

        try
        {
            addin.SelectionStart = selectionStart;
            addin.SelectionLength = token.Length;

            Clipboard.SetImage(smiley);
            addin.Paste();
        }
        catch (Exception ex)
        {
            MessageBox.Show(e.Message);
            break;
        }
    }
}