![](/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.