Wpf多线程

Wpf multithreading

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
});

这是我的代码。我想多线程在tabControl中添加tabitem。但是我在 "PROBLEM IS HERE" 处收到“调用线程无法访问此对象,因为另一个线程拥有它。”错误。

我的其他问题:

您的名为 tiTabItem 不是在 UI 线程上创建的。 你应该在 UI 线程上创建它,这样你就可以像这样包装它:

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;
  });

WPF 应用中与您的任务相关的多线程功能的简单(但不一定是最佳)实现如下所示:

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; }
     }
}

假设您在 XAML 中放置了 TabControl1,此代码将动态添加另一个 TabItem ti 并在异步中设置其 header/content 属性使用 asyncawait 编码技术的模式。在现实生活中的应用程序中,它可能应该封装在 Button.Click 事件处理程序或类似的东西中(作为一般规则,async void 主要用于 UI event 处理) .

希望这可能有所帮助。

@EngineerSpock 通过电子邮件解决了我的问题。

问题出在我的用户控件中,那个 durumButon。

新密码:

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");
            }));
        }
    }

我添加 Application.Current.Dispatcher.Invoke(new Action(() =>{})); 代码块,我的问题就解决了。