编辑ObservableCollection中的listView项调用XamlParseException(需要DependencyObject) - WPF

时间:2013-01-09 23:43:17

标签: c# wpf listview binding edit

我是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。非常感谢大家帮助我。我期待着您的回复,我已准备好向您展示您需要的所有代码。

1 个答案:

答案 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相关的活动。