Вопрос

Without getting too much into the "why" I need to do this, here is my situation. I need to create an INativeHandleContract to pass a UserControl over an AppDomain boundary, from a new AppDomain into the main AppDomain, where it is then added to a StackPanel. But I am also trying to do this in a different thread. I ran in to a situation where it appears the UserControl is being added correctly if this all runs in the same thread. If I add the UserControl to the StackPanel from a separate thread, it seems to get added but nothing appears on screen. So I boiled this down to the following code and found where the difference is. First the working code:

private void AddTestControlInNewThread()
{
    System.Threading.Thread t = new System.Threading.Thread(AddTestControl);
    t.SetApartmentState(System.Threading.ApartmentState.STA);
    t.Start();
}

private void AddTestControl()
{
    INativeHandleContract contract;
    FrameworkElement fe;

    Dispatcher.Invoke(new Action(() => 
    {
        contract = FrameworkElementAdapters.ViewToContractAdapter(new Label() { Content = DateTime.Now.ToString() });
        fe = FrameworkElementAdapters.ContractToViewAdapter(contract);
        parentStackPanel.Children.Add(fe);

    }), null);
}

That works just fine, however, in my scenario, I cannot create the "contract" inside of the Dispatcher.Invoke call. So I moved it to just outside of that and that's where thing stop working. Here is the difference in code:

private void AddTestControl()
{
    INativeHandleContract contract;
    FrameworkElement fe;

    contract = FrameworkElementAdapters.ViewToContractAdapter(new Label() { Content = DateTime.Now.ToString() });

    Dispatcher.Invoke(new Action(() => 
    {

        fe = FrameworkElementAdapters.ContractToViewAdapter(contract);
        parentStackPanel.Children.Add(fe);

    }), null);
}

Can anyone shine some light on why the user control would not show up, even if it does get added to the parentStackPanel's Children collection successfully? Thanks in advance.

Это было полезно?

Решение

I'd love to know the why behind your unique situation. I'm assuming that the Dispatcher is associated with the same thread on which parentStackPanel is created. WPF controls have thread-affinity and all of them must be modified from the same thread. You are constructing a Label object which in your first example, is constructed in the same thread as the StackPanel which is good. In your second example, it is constructed on a different thread which is most likely why the code is not working. Attach with a debugger and you ought to catch some sort of exception being thrown.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top