【问题标题】:Load control throws The calling thread cannot access this object...负载控制抛出调用线程无法访问此对象...
【发布时间】:2013-12-13 08:56:10
【问题描述】:

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

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

此时我得到 System.InvalidOperationException 和 Message=调用线程无法访问此对象,因为不同的线程拥有它。

代码:

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();
    }
}

那么如何更改对象的线程所有者?

试图在窗口对象上调用任何 Dispatcher 的“Invoke”方法都无济于事。

【问题讨论】:

    标签: c# wpf multithreading dispatcher


    【解决方案1】:

    您不能更改拥有线程。相反,您可以简化您的 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());
    }
    

    【讨论】:

      猜你喜欢
      • 2012-03-22
      • 1970-01-01
      • 2013-07-31
      • 1970-01-01
      • 2021-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多