Background worker needs to copy RichTextBox.rtf

Christ Kennedy 41 Reputation points
2022-02-23T12:26:41.27+00:00

my app is drawing a 'word-map' bitmap that identifies the locations of a given word inside a RichTextBox.

see code below:

                  RichTextBox rtxTemp = new RichTextBox(); // needed to set to UpperCase before searching word in text

                        rtxTemp.Rtf = ckRTX.rtx.Rtf;
                        rtxTemp.Text = rtxTemp.Text.ToUpper();

                        Point ptTopChar = ckRTX.rtx.GetPositionFromCharIndex(0);
                        Point ptLastChar = ckRTX.rtx.GetPositionFromCharIndex(ckRTX.rtx.Text.Length - 1);

                        string strLastChar = ckRTX.rtx.Text[rtxTemp.Text.Length - 1].ToString();

                        Size szLastChar = TextRenderer.MeasureText(strLastChar, ckRTX.rtx.Font);

                        Rectangle recSource = new Rectangle(0, 0, ckRTX.rtx.Width, ptLastChar.Y - ptTopChar.Y + szLastChar.Height);

                        dblFactorDraw = (double)Screen.PrimaryScreen.Bounds.Height / (double)recSource.Height;
                        Size szTextSource = TextRenderer.MeasureText(strWord, ckRTX.rtx.Font);
                        Size szDrawRec = new Size((int)(szTextSource.Width * dblFactorDraw), (int)(szTextSource.Height * dblFactorDraw));

                        Bitmap bmpDraw = new Bitmap((int)(recSource.Width * dblFactorDraw), (int)(recSource.Height * dblFactorDraw));
                        int intCounter = 0;
                        using (Graphics g = Graphics.FromImage(bmpDraw))
                        {
                            g.FillRectangle(Brushes.White, new RectangleF(0, 0, bmpDraw.Width, bmpDraw.Height));
                            int intIndex = rtxTemp.Text.IndexOf(strWord);
                            while (intIndex >= 0)
                            {
                                intCounter++;
                                char chrBefore = intIndex > 0
                                                          ? rtxTemp.Text[intIndex - 1]
                                                          : ' ';
                                char chrAfter = intIndex + strWord.Length < rtxTemp.Text.Length - 2
                                                                          ? rtxTemp.Text[intIndex + strWord.Length]
                                                                          : ' ';

                                if (!Char.IsLetter(chrBefore) && !Char.IsLetter(chrAfter))
                                {
                                    Point ptStart = ckRTX.rtx.GetPositionFromCharIndex(intIndex);
                                    Point ptDraw = new Point((int)(dblFactorDraw * ptStart.X), (int)(dblFactorDraw * (ptStart.Y - ptTopChar.Y)));
                                    g.FillRectangle(Brushes.Red, new Rectangle(ptDraw, szDrawRec));
                                }

                                try
                                {
                                    intIndex = rtxTemp.Text.IndexOf(strWord, intIndex + 1);
                                }
                                catch (Exception)
                                {

                                    intIndex = -1;
                                }

                            }

                        }
                        bmpDraw.MakeTransparent(Color.White);
                        rtxTemp.Dispose();
                        _bmpMapBase = bmpDraw;

-- this works and does what I want it to do but now I want this to be done by a BackgroundWorker. I've tried having the BackgroundWorker create it's own RichTextBox to work with but copying the original RTX's .RTF property to the BackgroundWorker's RTF property is causing a cross-threading error.
Is there a way to make a copy of the original RTX's RTF property (keeping its formatting) so that I can then initialize the BackgroundWorker's own RTX with the original's RTF?

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,922 questions
0 comments No comments
{count} votes

Accepted answer
  1. Viorel 117.3K Reputation points
    2022-02-23T12:52:29.75+00:00

    When you start the worker, you can pass the RTF in this manner:

    backgroundWorker1.RunWorkerAsync( ckRTX.rtx.Rtf );
    

    In the worker:

    void backgroundWorker1_DoWork( object sender, DoWorkEventArgs e )
    {
       RichTextBox rtxTemp = new RichTextBox( );
       rtxTemp.Rtf = (string)e.Argument;
       . . .
    }
    

    To pass more data, build a custom object.

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.