tags:

views:

848

answers:

1

In my Window constructor after InitializeComponents, I need to create an object and bind it to a datagrid. Since the object creation is taking too much time, the windows takes a while to show up. So I decided to move the creation of the object to a background thread and "delegate back" to the UI thread by doing a dispatcher.invoke to perform the binding. But this fails.

The weird thing is if I try to set the visibility of a rectangle I have inside the Dispatcher.invoke, that works but the DataGrid.setbinding doesnt! Any ideas? I have tried the same thing with background worker, and threadstart, but I keep getting the same error. I am not able to access the DataGrid object even though its happening inside the dispatcher invoke delegate. Am sure am missing something in my understanding of how this works. Any suggestions would be greatly appreciated. Thanks!

StartupDelegate s = new StartupDelegate(CreateModel);
s.BeginInvoke(delegate(IAsyncResult aysncResult) { s.EndInvoke(aysncResult); }, null);

internal CreateModel()
{
    Model d = new Model();
    Dispatcher.Invoke( DispatcherPriority.Normal, 
                       new Action<Model>(
                          delegate(Model d1)
                          {
                              mModel = d1;   // mModel is a property defined in Window
                              Binding b = new Binding();
                              b.Source = mModel; 
                              MainDataGrid.SetBinding(TreeView.ItemsSourceProperty, mainb); // << dies here with - The calling thread cannot access this object because a different thread owns it.
                          }            
}

UPDATE: Ended up using a dispatchertimer that would run just once. Putting the binding code in its Tick delegate worked. But I am still curious why the above code doesnt.

A: 

I would suggest another way around.

Binding should not be called from code, instead you should define it in XAML.

You can add one more DependencyProperty of type Model on your window and call it "CurrentModel" and set its initial value to NULL. Looks like you already have a property called mModel, is that DependencyProperty?

You can define Binding of CurrentModel to DataGrid or whichver control in XAML.

And in your end of delegate, the Dispatcher.Invoke should only set CurrentModel, the binding will be done automatically.

Akash Kava
I had tried this not in xaml but just setting the binding to the property, with the property inited to null. So the delegate had only one line mModel=d1. But nothing happened. Its not a dependancy property but an ordinary property implementing notifypropertychanged.
Klerk
I doubt because if the object is derived from DependencyObject (your window is), INotifyPropertyChanged does not work, even I had similar issue, thats why I changed it to DependencyProperty.
Akash Kava