0

I'm dynamically building my WPF layout and for some reason, when I try to add a control to a grid using a different thread, I'm getting:

System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'

I know that I need to be invoking my controls if they are being access from different threads and this is what I'm doing.

public void controlInvoke(Grid control, Action action)
{
    control.Dispatcher.Invoke((Delegate)action);
}

When I add a new row definition to my grid from the thread, it works fine.

controlInvoke(installedApplicationGrid, () =>
{
    installedApplicationGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
});  

The children are built from another method, which is below.

private StackPanel BuildAppPanel()
{
    StackPanel panel = new StackPanel();

    Grid innerGrid = new Grid();
    innerGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Star) });
    innerGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Star) });
    innerGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(100, GridUnitType.Star) });

    panel.Children.Add(innerGrid);

    return panel;
}

The actual code that generates the panel, and tries to add it to my Grid is.

StackPanel applicationPanel = BuildAppPanel();

controlInvoke(installedApplicationGrid, () =>
{
    installedApplicationGrid.Children.Add(applicationPanel);
});

It is at this point, when the error message shows. What I don't understand is why this is happening when all of the controls are being dynamically built using this thread. It doesn't make sense to me why adding the row definitions is fine, but adding a new control is not.

Could someone shed some light on this?

a--
  • 558
  • 2
  • 15

1 Answers1

0

So after looking at this a little more carefully, I fixed it by moving the BuildPanel inside of the action.

controlInvoke(installedApplicationGrid, () =>
{
    StackPanel applicationPanel = BuildAppPanel();
    installedApplicationGrid.Children.Add(applicationPanel);
});     

All is working now. Thanks @Fildor for the suggestion.

a--
  • 558
  • 2
  • 15
  • Just to explain why I asked: I guess the error was because "applicationPanel" was created on a different thread. So that Thread "owns" it. Moving creation into the action has the correct Thread own it. – Fildor Nov 23 '17 at 15:12