简体   繁体   中英

“The calling thread must be STA, because many UI components require this” while creating/adding new wpf usercontrol

I have a usertaskpane in VSTO add-in. I'm adding there winformshost and elementhost to be able to use wpf controls inside usertaskpane.

I managed to add a main wpf control, but I am failing with adding child user control to that.

I have such method that initiates adding new wpf control:

private void MasterCheck()
{
    this.pnlProgress.Visibility = System.Windows.Visibility.Visible;

    //I'm using progress bar functionality in ReturnMasters method
    Thread myNewThread = new Thread(() => Auditor.AuditMasterSlides(Globals.ThisAddIn.Application.ActivePresentation, this.pnlMaster, this, token));

    token = new CancellationTokenSource();
    myNewThread.Start();
    this.pnlProgress.Visibility = System.Windows.Visibility.Collapsed;
}

public static void AuditMasterSlides(PPT.Presentation pres, Panel panel, MainProofingTaskPaneControl control, CancellationTokenSource cancToken)
{
    IDictionary<string,MasterSlide> masterSlides = ReturnMasters(pres, cancToken, control);
    control.ShowAndCollapse(panel);
    control.RemovePanelChildren(panel);

    if (masterSlides.Count>1)
    {
        //control.AddControlToPanel(panel, new MasterCheckControlOK());
    }
    else
    {
        control.AddControlToPanel(panel, new MasterCheckControlOK());
    }
}

internal void RemovePanelChildren(Panel panel)
{
    this.Dispatcher.Invoke(() =>
    {
        for (int i = panel.Children.Count - 1; i >= 0; i--)
        {
            panel.Children.RemoveAt(i);
        }
    });
}

internal void AddControlToPanel(Panel panel, Control control)
{
    MasterCheckControlOK newControl = new MasterCheckControlOK();

    this.Dispatcher.Invoke(() =>
    {
        panel.Children.Add(newControl);
    });
}

And I'm getting error here:

public MasterCheckControlOK()
{
    InitializeComponent();
}

How can I solve it to be able to:

  • use progress bar functionality (currently works)
  • add new wpf controls (does not work)
  • modify/remove controls (currently works)
  1. You can only create UI controls on STA (single-threaded apartment) threads:

The calling thread must be STA, because many UI components require this

  1. You can only access a control on the thread on which it was originally created. For example, you cannot create a control on a thread B and then try to add it to the Children collection of a control that was created on thread A.

So it makes no sense to create a control on a background thread if you intend to interact with it one way or another from the main thread. Then you will get this exception.

Bottom line: You should create all controls on the same thread and this thread should in most cases be the main UI/dispatcher thread. This will save you a whole lot of trouble.

When you create a control it has to happen in the main UI thread. Currently you are creating the control in another thread and then adding it to another. This will cause an exception.

You need to move the creation of the control to happen inside the invoke so it happens on the main UI thread.

You can't create UI controls in separate threads. The control needs to exist on the UI thread.

You might try having your threaded function do its work through your window's Dispatcher using its .Invoke() methods.

You probably want to make sure that ONLY the manipulation of your UI controls is done with the dispatcher otherwise you'll probably lock up the UI anyway.

public static void AuditMasterSlides(PPT.Presentation pres, Panel panel, MainProofingTaskPaneControl control, CancellationTokenSource cancToken)
{
    IDictionary<string,MasterSlide> masterSlides = ReturnMasters(pres, cancToken, control);

    this.Dispatcher.Invoke((() => control.ShowAndCollapse(panel));
    ...
}

As for the STA thread issue, you need to specify that your thread is an STA thread before you start it.

I did this by calling .SetApartmentState() on my thread:

thread1.SetApartmentState(ApartmentState.STA);
thread1.Start();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM