是否可以在另一个线程中加载用户控件

本文关键字:加载 用户 控件 线程 另一个 是否 | 更新日期: 2023-09-27 18:37:22

我是wpf和多线程的新手。我有五个用户控件,A-B-C-D-E,然后回到A

我正在尝试在加载 B 时重新加载用户控件 A。

public class Main{
    public List<Page> pages;
    public UserControl currentScreen;
}
public class Page
{
    public UserControl userControl;
    public String xamlUrl;
    public void Invalidate()
    {
        try{
            var th = new Thread(() =>
            {
                ParseUserControl(xamlUrl);
            });
            th.SetApartmentState(ApartmentState.STA);
            th.Start();
        }
    }
    void ParseUserControl(String xamlUrl)
    {
        Console.WriteLine("ParseUserControl" + Thread.CurrentThread.ManagedThreadId);
        string strXaml = System.IO.File.ReadAllText(xamlUrl);
        UserControl uc = (UserControl)System.Windows.Markup.XamlReader.Parse(strXaml);
        UserControlParsedEventArgs args = new UserControlParsedEventArgs(uc);
        Application.Current.Dispatcher.Invoke(() => UserControlParsed(args));
    }

    void UserControlParsed(UserControlParsedEventArgs e)
    {
        Console.WriteLine("UserControlParsed " + Thread.CurrentThread.ManagedThreadId);
        userControl= e.userControl;
        Main.getInstance().currentScreen = userControl; //this line here throws error
    }
}

主要思想是让线程解析用户控件,加载用户控件后,我们将其发送回主屏幕进行显示。

但是,我收到此错误:"调用线程无法访问此对象,因为其他线程拥有它。

我认为这是因为用户控件是在不同的线程中创建的,但我已经做了UserControl uc = e.userControl。

我已经检查了线程 ID:

main is running on id 8 <----------------------
ParseUserControl is running on id 9           |---always same
UserControlParsed is running on id 8 <---------

所以UserControlParsad中的UserControl属于线程8,据说可以在main中使用?我很困惑。

是否可以在另一个线程中加载用户控件

根据这个答案:

在一个 (UI) 线程中创建的元素不能放入另一个元素的逻辑/可视化树中,该元素是在不同的 UI 线程上创建的。

混合在不同 UI 线程上创建的元素的解决方法技术:

有一种有限的解决方法技术,它可能会为您提供一些能力,将在一个 UI 线程中创建的元素的呈现与在不同线程中创建的可视化树组合在一起......通过使用主机视觉。请参阅此示例:

http://blogs.msdn.com/b/dwayneneed/archive/2007/04/26/multithreaded-ui-hostvisual.aspx

但这有点复杂。应将参数从后台线程传递到 UI 线程,并在 UI 线程上创建用户控件。