2013-12-13 1 views
0

Мне нужно загрузить файл XAML, но поскольку он работает только в контексте потока STA, мне нужно запустить новый поток и установить его состояние к STA.Load control throws Вызывающий поток не может получить доступ к этому объекту ...

После того, как управление загружено, я хочу получить все его логические дочерние элементы с помощью 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(); 
    } 
} 

Так как я могу изменить владельца нити объекта?

Привязка к вызову любого из методов «Invoke» Dispatcher на объекте окна не помогает.

ответ

0

Вы не можете изменить свою нить. Вместо этого вы можете упростить свой метод LoadUI.

Отбросьте все отдельные материалы и загрузите XAML напрямую, так как вызов Join будет блокировать ваш поток пользовательского интерфейса в любом случае до тех пор, пока поток нагрузки не завершится.

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()); 
} 
Смежные вопросы

 Смежные вопросы