0
UserControls.userGridGunler ug = new UserControls.userGridGunler();//My user control
ug.Basliklar.ItemsSource = basliklar;
ug.Saatler.ItemsSource = saha.Satirlar;

TabItem ti = new TabItem();
ti.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate
{
    ti.Header = saha.SahaAdı + " (" + saha.SahaTipi + ")";
    ti.Content = ug;
});

//tabSahalar is my TabControl in mainWindow

tabSahalar.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate
{
    tabSahalar.Items.Add(ti);//PROBLEM IS HERE
    //tabSahalar.Items.Add(new TabItem { Header = "asdasdad" });//Problem no here
});

This is my code. I want to multithreading add tabitem in tabControl. But I get "The calling thread cannot access this object because a different thread owns it." error at "PROBLEM IS HERE" place.

My other promlem : enter image description here

krlzlx
  • 5,752
  • 14
  • 47
  • 55
CaKaL
  • 402
  • 1
  • 6
  • 16
  • 2
    Your problem is the very common UI is on one thread and you cant play with it from another - please google, and look through stack overflow, theres a ton of this – BugFinder Mar 07 '16 at 15:41
  • 1
    See the sidebar, heading "Related", there are already several interesting answers listed there - we could probably close this question as a dupe of http://stackoverflow.com/questions/1792129/multithreaded-access-to-the-wpf-gui-in-c-sharp?rq=1 ? – fvu Mar 07 '16 at 15:45
  • Create the TabItem (`ti = new TabItem();`) in the Invoke action. – Clemens Mar 07 '16 at 15:46
  • 1
    @CaKaL Can you send me your solution via e-mail? – EngineerSpock Mar 08 '16 at 15:35
  • @EngineerSpock why not? Your e-mail address? – CaKaL Mar 09 '16 at 12:29

3 Answers3

2

Your TabItem named ti was created not on the UI thread. You should create it on the UI thread, so you can wrap it like this:

TabItem ti = null;
Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate
 {
   ti = new TabItem();
   ti.Header = saha.SahaAdı + " (" + saha.SahaTipi + ")";
   ti.Content = ug;
  });
EngineerSpock
  • 2,575
  • 4
  • 35
  • 57
  • This code has "**Object reference not set to an instance of an object**" error. Because ti=null yet. – CaKaL Mar 08 '16 at 07:06
  • 1
    @CaKaL I'm sorry, there should have been Application.Current.Dispatcher.Invoke(). Copy and try again. – EngineerSpock Mar 08 '16 at 13:32
  • I try this code but I get "**Must create DependencySource on same Thread as the DependencyObject**" error. :( – CaKaL Mar 08 '16 at 14:56
  • 1
    @CaKaL this is the other problem, though similar. basliklar or saha were created not on the UI-thread. You should create them on the UI thread applying the same technique - using Application.Current.Dispatcher. The problem of the topic is resolved. If not difficult, mark one of the answers as the answer. I'll try to help you in comments, or you can create another question. – EngineerSpock Mar 08 '16 at 15:05
0

The simple (but not necessarily optimal) implementation of the multi-threading functionality in WPF app pertinent to your task is shown below:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // this simulates some User event, e.g. Button click
        AddMyTabItem();
    }

    // in real-life app this could be replaced w/event handler
    private async void AddMyTabItem()
    {
        try
        {
            TabItem ti = new TabItem();
            ti.Header = "MyTableItemHeader";
            ti.Content = "MyTableItemContent";
            await AddTabItem(ti);
        }
        catch { }
    }

    // implements async/await asynchronous for responsive UI
    private async Task AddTabItem(TabItem TI)
    {
        try
        {
            await TabControl1.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)delegate
            {
                TabControl1.Items.Add(TI);
            });
        }
        catch { throw; }
     }
}

Assuming that you have TabControl1 placed in your XAML, this code will dynamically add another TabItem ti and set its header/content properties in asynchronous mode utilizing async and await coding technique. In a real-life app it should possibly be encapsulated in a Button.Click event handler or something similar (as a general rule, async void is recommended primarily for UI event handling).

Hope this may help.

Alexander Bell
  • 7,842
  • 3
  • 26
  • 42
0

@EngineerSpock solved my problem via e-mail.

The problem is in my User Control that durumButon.

New code :

public DURUM Durum
    {
        get
        {
            return _durum;
        }

        set
        {
            _durum = value;

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

                if (value == DURUM.DOLU)
                {
                    BGrenk = (SolidColorBrush)(new BrushConverter()).ConvertFromString("#FF740000");
                    IptalEtMenuItem = Visibility.Visible;
                    OdemeAlMenuItem = Visibility.Collapsed;
                    DetayMenuItem = Visibility.Visible;
                }
                else if (value == DURUM.KOMBİNE)
                {
                    BGrenk = (SolidColorBrush)(new BrushConverter()).ConvertFromString("#FF740000");
                    IptalEtMenuItem = Visibility.Collapsed;
                    OdemeAlMenuItem = Visibility.Visible;
                    DetayMenuItem = Visibility.Visible;

                }
                else if (value == DURUM.REZERVE)
                {
                    BGrenk = (SolidColorBrush)(new BrushConverter()).ConvertFromString("#00a8e6");
                    IptalEtMenuItem = Visibility.Visible;
                    OdemeAlMenuItem = Visibility.Visible;
                    DetayMenuItem = Visibility.Visible;
                }
                else if (value == DURUM.KAPORA)
                {
                    BGrenk = (SolidColorBrush)(new BrushConverter()).ConvertFromString("#ffd800");
                    IptalEtMenuItem = Visibility.Visible;
                    OdemeAlMenuItem = Visibility.Visible;
                    DetayMenuItem = Visibility.Visible;
                }
                else if (value == DURUM.BOŞ)
                {
                    BGrenk = (SolidColorBrush)(new BrushConverter()).ConvertFromString("#FF00AE18");
                    IptalEtMenuItem = Visibility.Collapsed;
                    OdemeAlMenuItem = Visibility.Visible;
                    DetayMenuItem = Visibility.Collapsed;
                }

                OnPropertyChanged("DURUM");
            }));
        }
    }

I add Application.Current.Dispatcher.Invoke(new Action(() =>{})); code block and my problem has solved.

CaKaL
  • 402
  • 1
  • 6
  • 16