![](/img/trans.png)
[英]The calling thread must be STA, because many UI components require this in WPF
[英]“The calling thread must be STA, because many UI components require this” while creating/adding new wpf usercontrol
我在VSTO加載項中有一個usertaskpane。 我在其中添加winformshost和elementhost以便能夠在usertaskpane中使用wpf控件。
我設法添加了一個主要的wpf控件,但是我未能在其中添加子用戶控件。
我有這樣的方法可以啟動添加新的wpf控件:
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);
});
}
而且我在這里出錯:
public MasterCheckControlOK()
{
InitializeComponent();
}
我該如何解決它才能:
Children
集合中。 因此,如果您打算與主線程以一種或多種方式進行交互,則在后台線程上創建控件是沒有意義的。 然后,您將獲得此異常。
底線:您應該在同一線程上創建所有控件,並且在大多數情況下,該線程應該是UI / dispatcher主線程。 這將為您省去很多麻煩。
創建控件時,它必須在主UI線程中發生。 當前,您正在另一個線程中創建控件,然后將其添加到另一個線程中。 這將導致異常。
您需要將控件的創建移動到調用內部,以便控件發生在主UI線程上。
您不能在單獨的線程中創建UI控件。 該控件需要存在於UI線程上。
您可以嘗試使用其.Invoke()
方法在窗口的Dispatcher .Invoke()
線程函數完成其工作。
您可能要確保僅通過分派器完成對UI控件的操作,否則可能仍會鎖定UI。
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));
...
}
對於STA線程問題,您需要在啟動之前指定您的線程是STA線程。
我是通過在線程上調用.SetApartmentState()
來完成此操作的:
thread1.SetApartmentState(ApartmentState.STA);
thread1.Start();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.