C# 加载控制引发调用线程无法访问此对象。。。

C# 加载控制引发调用线程无法访问此对象。。。,c#,wpf,multithreading,dispatcher,C#,Wpf,Multithreading,Dispatcher,我必须加载一个XAML文件,但因为它只在STA线程的上下文中起作用,所以我必须启动一个新线程并将其单元状态设置为STA 加载控件后,我希望使用LogicalTreeHelper.GetChildren(…)获取其所有逻辑子级 此时,我得到System.InvalidOperationException,消息为=调用线程无法访问此对象,因为它是另一个线程拥有的 守则: public partial class MainWindow : Window { private Thread STA

我必须加载一个XAML文件,但因为它只在STA线程的上下文中起作用,所以我必须启动一个新线程并将其单元状态设置为STA

加载控件后,我希望使用LogicalTreeHelper.GetChildren(…)获取其所有逻辑子级

此时,我得到System.InvalidOperationException,消息为=调用线程无法访问此对象,因为它是另一个线程拥有的

守则:

public partial class MainWindow : Window
{
    private Thread STAThread = null;
    /// <summary>
    /// XAML path.
    /// </summary>
    private static string _selectedXAML = Path.GetFullPath( @"..\..\Resources\UserControl1.xaml" );

    private FrameworkElement _loadedUI = null;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void MainWindow_OnLoaded( object sender, RoutedEventArgs e )
    {
        this.LoadUI();
        DependencyObject depObj = _loadedUI as DependencyObject;

        var s = LogicalTreeHelper.GetChildren( depObj );
    }

    private void LoadUI()
    {
        // Read the text as string from the file
        var xamlText = File.ReadAllText( _selectedXAML );

        // Replace variable values and script value pairs
        StringReader stringReader = new StringReader( xamlText );
        XmlReader xmlReader = XmlReader.Create( stringReader );

        STAThread = new Thread(
            () =>
            {
                _loadedUI = XamlReader.Load( xmlReader ) as FrameworkElement;
            } );


        STAThread.SetApartmentState( ApartmentState.STA );

        STAThread.Start();

        STAThread.Join();
    }
}
公共部分类主窗口:窗口
{
私有线程statthread=null;
/// 
///XAML路径。
/// 
私有静态字符串\u selectedXAML=Path.GetFullPath(@“.\..\Resources\UserControl1.xaml”);
私有框架元素_loadedUI=null;
公共主窗口()
{
初始化组件();
}
私有void主窗口\u已加载(对象发送方,路由目标)
{
这是LoadUI();
DependencyObject depObj=_loadedUI作为DependencyObject;
var s=logicaltreeheloper.GetChildren(depObj);
}
私有void LoadUI()
{
//从文件中以字符串形式读取文本
var xamlText=File.ReadAllText(_selectedXAML);
//替换变量值和脚本值对
StringReader StringReader=新StringReader(xamlText);
XmlReader=XmlReader.Create(stringReader);
STAThread=新线程(
() =>
{
_loadedUI=XamlReader.Load(xmlReader)作为FrameworkElement;
} );
SetApartmentState(ApartmentState.STA);
statthread.Start();
statthread.Join();
}
}
那么如何更改对象的线程所有者?


绑定在窗口对象上调用任何Dispatcher的“invoke”方法都没有帮助。

您不能更改所属线程。相反,您可以简化
LoadUI
方法

删除所有单独的线程内容并直接加载XAML,因为
Join
调用将阻塞UI线程,直到加载线程完成

private FrameworkElement LoadUI()
{
    // Read the text as string from the file
    var xamlText = File.ReadAllText(_selectedXAML);

    // Replace variable values and script value pairs
    var stringReader = new StringReader(xamlText);
    var xmlReader = XmlReader.Create(stringReader);

    return XamlReader.Load(xmlReader) as FrameworkElement;
}

private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
    var s = LogicalTreeHelper.GetChildren(LoadUI());
}