0

I've created a custom Rich Text box in my .Net winform application, and I'm facing a strange issue. The goal is append Text to the rich text box with a specific formating, all of this within another thread. For this I've created delegates callback. As soon as I start using any of the "Selection" property from the rich text box, I get a cross_thread Exception, but in the Controls.add(control) fonction...

Here's the different codes :

Main Form

public partial class NotificationForm : Form
{
    private ProductLayout productLayout = null;
    delegate void AddControlDelegate(Control control);
    delegate void ClearControlDelegate();

    public NotificationForm()
    {
        InitializeComponent();
        productLayout = new ProductLayout();
    }

    public void SetProductContent(ProductResponse product)
    {
        ClearControls();
        productLayout.SetProductContent(product);
        AddControl(productLayout);
    }

    public void ClearControls()
    {
        if (InvokeRequired)
        {
            ClearControlDelegate d = new ClearControlDelegate(ClearControls);
            Invoke(d);
        }
        else
        {
            foreach (Control ctrl in Controls)
            {
                Controls.Remove(ctrl);
            }
        }
    }

    public void AddControl(Control control)
    {
        if (InvokeRequired)
        {
            AddControlDelegate d = new AddControlDelegate(AddControl);
            Invoke(d, new object[] { control });
        }
        else
        {
            // Cross Thread Error thrown here complaining about access of rtb_content
            Controls.Add(control);
        }
    }
}

User Control

public partial class ProductLayout : UserControl
{
    delegate void SetProductCallback(ProductResponse product);

    public ProductLayout()
    {
        InitializeComponent();
    }

    public void SetProductContent(ProductResponse product)
    {
        if(InvokeRequired)
        {
            SetProductCallback d = new SetProductCallback(SetProductContent);
            Invoke(d, new object[] { product });
        } else
        {
            // My custom rich text box
            rtb_content.AppendText(product.name_prefix, Color.Black);
            rtb_content.AppendText(product.name, Color.Black);
        }
    }
}

Custom Rich text box

public partial class EnhancedTextBox : RichTextBox
{
    delegate void AppendTextCallback(string text, Color color);

    public EnhancedTextBox()
    {
        InitializeComponent();
    }

    public void AppendText(string text, Color color)
    {
        if (InvokeRequired)
        {
            AppendTextCallback d = new AppendTextCallback(AppendText);
            Invoke(d, new object[] { text, color });
        }
        else
        {
            SelectionStart = TextLength;
            SelectionLength = 0;

            SelectionColor = color;
            SelectionFont = font;
            AppendText(text);
            SelectionColor = ForeColor;
        }
    }
}

If I remove the Selection actions in the AppendText and only let the line Text += text everything works fine. I really don't understand why the error is thrown when adding the control, and is there any specific knowledge I need to have about Selection actions ?

TmZn
  • 399
  • 5
  • 16
  • Well, that tells you that you can't add a control created in a thread A in a control's collection which is created in thread B. Do you really need all that multi-threading? Everything is possible. –  Nov 08 '19 at 16:24
  • But why does it work when I remove the « Selection » actions ? It doesn’t make any sense to me, and I’m pretty sure there’s something else here. – TmZn Nov 08 '19 at 16:27

0 Answers0