Issue with accessing UI in ViewModel using WPF - MVVM The calling thread cannot access this object because a different thread owns it

I am trying to update a grid in the ViewModel

string fileName = SelectedView + ".xml";
                    PivotGridControl pivotGrid = App.Current.Windows[0].FindName("pivotGrid") as PivotGridControl;
                    pivotGrid.RestoreLayoutFromXml(fileName);

This gives me an error
The calling thread cannot access this object because a different thread owns it
How can I get arround this

I also tried the following, but get the same error.
  Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
                {
                    string fileName = SelectedView + ".xml";
                    PivotGridControl pivotGrid = App.Current.Windows[0].FindName("pivotGrid") as PivotGridControl;
                    pivotGrid.RestoreLayoutFromXml(fileName);
                                 }));
LVL 1
countrymeisterAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

apeterCommented:
Did you try with BeginInvokie ?

Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() =>
                {
                    string fileName = SelectedView + ".xml";
                    PivotGridControl pivotGrid = App.Current.Windows[0].FindName("pivotGrid") as PivotGridControl;
                    pivotGrid.RestoreLayoutFromXml(fileName);
                                 }));

or call the dispatcher from the control itself.

PivotGridControl pivotGrid = App.Current.Windows[0].FindName("pivotGrid") as PivotGridControl;
pivotGridDispatcher.Dispatcher.Invoke(
      System.Windows.Threading.DispatcherPriority.Normal,
      new Action(
        delegate()
        {
            string fileName = SelectedView + ".xml";
           pivotGrid.RestoreLayoutFromXml(fileName);        
    ));
0
countrymeisterAuthor Commented:
BeginInvoke did not work, and I cannot call the dispatcher on the control itself.
Because I  am using mVVM and this line fails

PivotGridControl pivotGrid = App.Current.Windows[0].FindName("pivotGrid") as PivotGridControl;

First I need to access the control, can't call the dispatcher until I have access to it.
0
apeterCommented:
Looks like from below link, PivotGridControl doesn't support binding.

http://www.devexpress.com/Support/Center/Question/Details/S137840

Maybe you can relax the MVVM in this scenario.
0
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

countrymeisterAuthor Commented:
I did relax the MVVM and accessed the viewmodel in the view itself, but my progress image shows with no animation , not sure what thread priority would do this.

        private void StartViewBackgroundThread()
        {
            var viewModel = (PnLViewModel)DataContext;
            viewModel.IsControlVisible = true;
            BackgroundWorker bgWorker = new BackgroundWorker();          
            bgWorker.WorkerSupportsCancellation = true;
            bgWorker.DoWork += new DoWorkEventHandler(viewChangedWorker_DoWork);
            bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(viewChangedWorker_RunWorkerCompleted);
            bgWorker.RunWorkerAsync();
        }

        void viewChangedWorker_DoWork(object sender, DoWorkEventArgs e)
        {            
            BackgroundWorker bgWork = (BackgroundWorker)sender;
            if ((bgWork.CancellationPending == true)) { e.Cancel = true; }
            else
            {
                pivotGrid.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.SystemIdle, new Action(
                 delegate()
                 {
                     string fileName = cbViews.SelectedValue.ToString() + ".xml";
                     pivotGrid.RestoreLayoutFromXml(fileName);
                     pivotGrid.Fields["Pnl"].CellFormat = "n0";
                     pivotGrid.Fields["Pnl"].ValueFormat = "n0";

                 }));              
             
            }
        }

        void viewChangedWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var viewModel = (PnLViewModel)DataContext;
            viewModel.IsControlVisible = false;
            viewModel.IsDataGridVisible = false;
        }
0
apeterCommented:
Try Dispatcher priority with "background" and not system idle.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
countrymeisterAuthor Commented:
I did that but same results..
0
apeterCommented:
Where is the progress images code, i am not seeing the logic in side "StartViewBackgroundThread" method...
0
countrymeisterAuthor Commented:
The progess image is an animation gif that I display .
I am using the WpfAnimatedGIF dll, here is the xaml for that

 <Image Name="imgProgress" Margin="12,0,8,4" Grid.Row="1"  Grid.Column="13" gif:ImageBehavior.AnimatedSource="Images/progress_bar.gif" >
                            <Image.Style>
                                <Style>
                                    <Setter Property="Image.Visibility" Value="Hidden"/>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsControlVisible}" Value="true">
                                            <Setter Property="Image.Visibility" Value="Visible"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Image.Style>
                        </Image>
0
apeterCommented:
Shouldn't you update this property to "False" , before or after calling you background worker method. And set to "true" when the background thread fires the completed event ?
0
countrymeisterAuthor Commented:
it should be opposite, because the background thread has the long running processs.
So you want to show the progress bar andthen when the process is complted hide it(make it false)
0
countrymeisterAuthor Commented:
Did not provide any good solution
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.