我有一个包含文件名的listview。我有另一个listview,其中包含重命名这些文件的可能操作。最后,我有一个显示结果预览的标签。当一个对象在每个列表中被选中时,我想显示预览。您只能选择一个文件,但可以选择一个或多个操作。我使用WPF/Xaml作为我的UI。我选择用线程来执行预览。
这是我的一部分代码:
private Thread _thread;
public MainWindow()
{
InitializeComponent();
_thread = new Thread(DoWork);
}
public void DoWork()
{
while (true)
{
FileData fileData = listViewFiles.SelectedItem as FileData; // ERROR HERE
if (fileData != null)
{
string name = fileData.FileName;
foreach (var action in _actionCollection)
{
name = action.Rename(name);
}
previewLabel.Content = name;
}
Thread.Sleep(1000);
}
}
private void listViewFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_thread.Start();
}
在运行时,我得到错误"调用线程不能访问这个对象,因为一个不同的线程拥有它。"在FileData FileData = listViewFiles。SelectedItem作为FileData;线。你知道我该怎么做吗?
你不能从非UI线程修改或访问UI。因此,如果你仍然想使用不同的线程,你需要做的第一件事是添加某种模型(有关绑定和模型的更多信息,请尝试搜索"wpf mvvm"),然后将你的listViewFiles.SelectedItem
绑定到这个模型的一些属性,这将允许你跨线程访问SelectedValue。其次,你需要将所有改变UI的逻辑分离为方法或使用lambda,所以最后它看起来像这样:
public void DoWork()
{
while (true)
{
FileData fileData = Model.SelectedValue;
if (fileData != null)
{
string name = fileData.FileName;
foreach (var action in _actionCollection)
{
name = action.Rename(name);
}
this.Dispatcher.Invoke((Action)()=> //use Window.Dispatcher
{
label3.Content = fileData.FileName;
label4.Content = name;
});
}
Thread.Sleep(1000);
}
}
乌利希期刊指南。关于与UI同步的一些附加说明:在WPF中,每个UI对象都继承自DispatcherObject类。因此,对该类型对象的所有访问只能从创建该对象的线程中进行,如果你想从另一个线程访问DispatcherObject(DO),你需要使用DO.Dispatcher.Invoke(Delegate)
方法,这将使你的代码排队到DO线程。综上所述,要在UI线程中运行代码,你需要使用任何UI元素的Dispatcher,在这种情况下,我们使用窗口的Dispatcher(假设代码在窗口代码后面)。
简单的回答是你不能这样做:线程A不能直接访问线程B创建的winforms对象(控件)
在实践中,你可以使用委托来安全地在另一个线程上运行:
form.Invoke(new MethodInvoker(() => {
FileData fileData = listViewFiles.SelectedItem as FileData; // ERROR HERE
if (fileData != null)
{
string name = fileData.FileName;
foreach (var action in _actionCollection)
{
name = action.Rename(name);
}
previewLabel.Content = name;
}
}));
然而,你可能只是想使用后台worker: http://msdn.microsoft.com/en-us/library/8xs8549b.aspx
详情见:http://weblogs.asp.net/justin_rogers/pages/126345.aspx