Bas*_*mme 0 c# xaml multithreading
我有一个包含文件名的列表视图.我有另一个列表视图,其中包含重命名这些文件的可能操作.最后,我有一个标签,显示结果的预览.当在每个列表中选择一个对象时,我想显示预览.您只能选择一个文件,但只能选择一个或多个操作.我使用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();
}
Run Code Online (Sandbox Code Playgroud)
在运行时我收到错误"调用线程无法访问此对象,因为另一个线程拥有它." 在FileData fileData = listViewFiles.SelectedItem上作为FileData; 线.你知道我该怎么办?
您无法从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);
}
}
Run Code Online (Sandbox Code Playgroud)
UPD.关于与UI同步的一些附加信息:在WPF中,每个UI对象都继承自DispatcherObject类.因此,只能从创建此对象的线程进行对此类对象的所有访问,如果要从另一个需要使用DO.Dispatcher.Invoke(Delegate)方法的线程访问DispatcherObject(DO),则会将代码排入DO线程.因此,总而言之,在UI线程中运行代码需要使用任何UI元素的Dipatcher,在这种情况下我们使用Window的Dispatcher(假设后面的窗口代码中的代码).
| 归档时间: |
|
| 查看次数: |
2207 次 |
| 最近记录: |