when add emoticon to RichTextBox Error (**An item with the same key has already been added**)

I try to add emoticon in RichTextBox in WPF that use function below, when I type text :) from Textbox, it shows the good result but when I type the other text again it show error (An item with the same key has already been added).this is code that i call from function Emoticons below :

   private void btnSend_Click(object sender, RoutedEventArgs e)
     {
        Paragraph p = new Paragraph();
        p.LineHeight = 1;
        Run dd = new Run();
        dd.Text= DateTime.Now.ToString("(HH:mm:ss)") + "Chat" + rtbMessage.Text;
        rtbBody.Document.Blocks.Add(p);
        Emoticons(dd.Text);     
    }

I type to fix it but still not solve. I hope all programmer will help me. Thanks

///Function Emoticon////

private Dictionary<string, string> _mappings = new Dictionary<string, string>();
        private string GetEmoticonText(string text)
    {


        string match = string.Empty;
        int lowestPosition = text.Length;

        foreach (KeyValuePair<string, string> pair in _mappings)
        {
            if (text.Contains(pair.Key))
            {
                int newPosition = text.IndexOf(pair.Key);
                if (newPosition < lowestPosition)
                {
                    match = pair.Key;
                    lowestPosition = newPosition;
                }
            }
        }

        return match;

    }
       // And also function which add smiles in richtextbox, here is it:

    private void Emoticons(string msg)
    {
        //try
        //{
            _mappings.Add(@":)", "/Images/smiles/silly.png");
            _mappings.Add(@">:o", "/Images/smiles/angry.png");
            _mappings.Add(@":'(", "/Images/smiles/cry.png");
            _mappings.Add(@"B-)", "/Images/smiles/cool.png");
            _mappings.Add(@":^0", "/Images/smiles/laught.png");
            _mappings.Add(@":-[", "/Images/smiles/blush.png");
            _mappings.Add(@":-)", "/Images/smiles/happy.png");
            _mappings.Add(@"?:|", "/Images/smiles/confuse.png");
            _mappings.Add(@":x", "/Images/smiles/love.png");


            var para = new Paragraph { LineHeight=1};
            //Paragraph para = new Paragraph();

            var r = new Run(msg);

            para.Inlines.Add(r);

            string emoticonText = GetEmoticonText(r.Text);

            //if paragraph does not contains smile only add plain text to richtextbox rtb2
            if (string.IsNullOrEmpty(emoticonText))
            {
                rtbBody.Document.Blocks.Add(para);
            }
            else
            {
                while (!string.IsNullOrEmpty(emoticonText))
                {

                    TextPointer tp = r.ContentStart;

                    // keep moving the cursor until we find the emoticon text
                    while (!tp.GetTextInRun(LogicalDirection.Forward).StartsWith(emoticonText))

                        tp = tp.GetNextInsertionPosition(LogicalDirection.Forward);

                    // select all of the emoticon text
                    var tr = new TextRange(tp, tp.GetPositionAtOffset(emoticonText.Length)) { Text = string.Empty };

                    //relative path to image smile file
                    string path = _mappings[emoticonText];

                    var image = new Image
                    {
                        Source =
                            new BitmapImage(new Uri(Environment.CurrentDirectory + path,
                                                    UriKind.RelativeOrAbsolute)),
                       Width=Height=25,
                    };

                    //insert smile
                    new InlineUIContainer(image, tp);

                    if (para != null)
                    {
                        var endRun = para.Inlines.LastInline as Run;

                        if (endRun == null)
                        {
                            break;
                        }
                        else
                        {
                            emoticonText = GetEmoticonText(endRun.Text);
                        }

                    }

                }
                rtbBody.Document.Blocks.Add(para);

            }

Answers

The reason you are getting this error is because you are adding an object in the dictionary with the same key, infact you are adding all the items in the _mappings dictionary on each call of your function Emoticons. You can't add duplicate entries in the dictionary. I have no idea why you are doing that, but you may fill up the dictionary once in your application startup or window load event and then use it later.

Move the following lines to any method/event where it would be executed only once.

_mappings.Add(@":)", "/Images/smiles/silly.png");
_mappings.Add(@">:o", "/Images/smiles/angry.png");
_mappings.Add(@":'(", "/Images/smiles/cry.png");
_mappings.Add(@"B-)", "/Images/smiles/cool.png");
_mappings.Add(@":^0", "/Images/smiles/laught.png");
_mappings.Add(@":-[", "/Images/smiles/blush.png");
_mappings.Add(@":-)", "/Images/smiles/happy.png");
_mappings.Add(@"?:|", "/Images/smiles/confuse.png");
_mappings.Add(@":x", "/Images/smiles/love.png");

Posted on by Habib

Relevant tags