我有一个包含文件名的列表视图。我有另一个列表视图,其中包含重命名这些文件的可能操作。最后,我有一个标签,显示结果的预览。当在每个列表中选择一个对象时,我想显示预览。您只能选择一个文件,但只能选择一个或多个操作。我使用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;线。你知道我该怎么办吗?
答案 0 :(得分:5)
您无法从nonUI线程修改或访问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);
}
}
UPD。关于与UI同步的一些额外的话:在WPF中,每个UI对象都继承自DispatcherObject类。因此,只能从创建此对象的线程进行对此类对象的所有访问,如果要从另一个需要使用DO.Dispatcher.Invoke(Delegate)
方法的线程访问DispatcherObject(DO),这会将您的代码排入队列DO线程。因此,总而言之,在UI线程中运行代码需要使用任何UI元素的Dipatcher,在这种情况下我们使用Window的Dispatcher(假设后面的窗口代码中的代码)。
答案 1 :(得分:-1)
简单的答案是你不能这样做:线程A不能直接访问线程B创建的winforms对象(控件)。
实际上,您可以使用委托在另一个线程ala上安全地运行它:
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;
}
}));
但是,你可能只想 使用后台工作人员:http://msdn.microsoft.com/en-us/library/8xs8549b.aspx
更详细地说:http://weblogs.asp.net/justin_rogers/pages/126345.aspx