我是C#和WPF编程的初学者,我正在创建一个包含2 ListView
s的文件管理器,所有项目都有限。在ListView
中有一些GridViewColumn
,第一个有CellTemplate
,因为我想要文件/文件夹的图标及其名称。 CellTemplate
是:
<DataTemplate x:Key="IconTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Source="{Binding Path=itemIcon}" Width="20" Grid.Column="0"/>
<TextBlock Grid.Column="1" Text="{Binding Path=itemName}" />
</Grid>
</DataTemplate>
我有一个Class:ObservableCollection,其中所有目录和文件都被添加到集合中,并且对于每个文件,其图标都是从文件转换而来的。 MyItem类包含名称,扩展名等的几个字符串以及这些图标的一个ImageSource。一切顺利,直到我意识到由于转换这些图标,一些具有不同文件的文件夹冻结了程序。所以现在我为每个文件绑定一些通用图标,然后我想转换并在另一个线程中更改它。所以在主类中我为项创建了全局ObservableCollection,因为我不知道如何从listView加载它们,我已经将填充Collection函数从Observable-class移动到了主类。现在我可以从新线程更改listview中的项目但是 - 最后这里出现了我的问题 - 我得到了XamlParseException - 必须在与DependencyObject相同的Thread上创建DependencySource。当我试图更改文件的名称(字符串)时,它工作得很好(到目前为止我只在点击按钮时测试它)!我尝试根据我在互联网上找到的一些参考来实现dependencyObject到MyItem类,但它没有用。这个改变图标的功能。
for (int i = leftDirectories.Length; i < (leftDirectories.Length + leftFiles.Length); i++)
{
FileToImageIconConverter some = new FileToImageIconConverter(locationLeft + leftFiles[i - leftDirectories.Length].Name);
ImageSource imgSource = some.Icon;
leftFilesLoad[i].itemIcon = imgSource;
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
{
contentLeft.Items.Refresh();
}
);
相当长的文章,stackoverflow说具体:-D。非常感谢大家帮助我。我期待着您的回复,我已准备好向您展示您需要的所有代码。
答案 0 :(得分:1)
发生异常是因为您在非UI线程上创建ImageSource
。除非你冻结对象,否则你不能这样做。您将希望所有与UI相关的逻辑都包含在BeginInvoke
调用中。试试这个
for (int i = leftDirectories.Length; i < (leftDirectories.Length + leftFiles.Length); i++)
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
{
FileToImageIconConverter some = new FileToImageIconConverter(locationLeft + leftFiles[i - leftDirectories.Length].Name);
ImageSource imgSource = some.Icon;
leftFilesLoad[i].itemIcon = imgSource;
contentLeft.Items.Refresh();
}
);
}
这应该在UI线程上保留所有与UI相关的活动。