0

This is my first question here. I'm begining with XAML and C#, hope I can explain my problem and get some help. I'm afraid that my approach is not possible to implement, but maybe I could get some help with a workaround.

I need to print lots of cards. The process is running but freezes the main thread. I would like to do this bulk printing inside a BackgroundWorker and report progress in the main thread. I found some examples of how to do it and I created all the stuff necessary to run the backgroundworker.

The problem is that for each card, I create an stackpanel where I build the picture and finally print it using a FixedDocument and a printdialog.

Code crashes in the first line of the class accreditation_graphic

        void m_oWorker_DoWork(object sender, DoWorkEventArgs e)
        {
        ObservableCollection<accreditation_field> _acc_list;
        _acc_list = _param_acc_list;

        accreditation_graphic _graphic = new accreditation_graphic();



        // The sender is the BackgroundWorker object we need it to
        // report progress and check for cancellation.
        //NOTE : Never play with the UI thread here...
        foreach (accreditation_field _acc in _acc_list)
        { [...] }
        [...]
    }

The class is:

    class accreditation_graphic
{
    private StackPanel _stack = new StackPanel();


    public accreditation_graphic()
    {


    }

[...]

And the thread finishes with no error in: private StackPanel _stack = new StackPanel();

Is there any way to create an stackpanel in a backgroundworkers?

Thanks.

FerBcn
  • 1
  • See [this question](http://stackoverflow.com/q/2763323/1136211). It is however possible to create UI elements in a different thread, provided that you set it to STA (single thread apartment). But it won't be (easily) possible to use those elements in the UI thread. They are completely separated. – Clemens Sep 19 '15 at 09:13

1 Answers1

1

The correct approach is to use your background worker thread to create the data that will be displayed on the UI but not the actual UI elements. You can use the progress report mechanism to report that data to the UI thread. Have the code on the UI thread pick that data and use it to generate the actual UI elements.

An even better solution: replace StackPanel with ItemsContainer (or an inheritor of ItemsContainer) and use data binding. Briefly here are some more details:

  • In XAML use an ItemsContainer or a class inherited from ItemsContainer.
  • In XAML set the ItemsSource of the ItemsContainer via data binding to an observable collection stored in a view model (that is whatever you set the DataContext of the control / page to).
  • In XAML use a data template to visualize each element from the ItemsSource.
  • Use the progress report mechanism to bring the data from the background thread and transfer it to the observable collection that is the source of the data binding.

BTW, if you are just starting with C# / XAML take the time to learn about databinding and MvvM, it will be worth your time.

Another suggestion: look at the new async / await in C#. You should use that instead of the background worker.

Ladi
  • 1,274
  • 9
  • 17