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" 处收到“调用线程无法访问此对象,因为另一个线程拥有它。”错误。
我的其他问题:
您的名为 ti
的 TabItem
不是在 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 属性使用 async
和 await
编码技术的模式。在现实生活中的应用程序中,它可能应该封装在 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(() =>{})); 代码块,我的问题就解决了。
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" 处收到“调用线程无法访问此对象,因为另一个线程拥有它。”错误。
我的其他问题:
您的名为 ti
的 TabItem
不是在 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 属性使用 async
和 await
编码技术的模式。在现实生活中的应用程序中,它可能应该封装在 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(() =>{})); 代码块,我的问题就解决了。