0

我是 C# 和 WPF 编程的初学者,我正在创建一个 2 ListViews 的文件管理器,所有项目都有界。里面有ListView一些GridViewColumns 和 first hasCellTemplate因为我想要文件/文件夹的图标及其名称。是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 移动到主类。现在我' 我能够从新线程更改列表视图中的项目,但 - 最后是我的问题 - 我得到 XamlParseException - 必须在与 DependencyObject 相同的线程上创建 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。非常感谢所有试图帮助我的人。我期待着您的回复,我已准备好向您展示您需要的所有代码。

4

1 回答 1

1

发生异常是因为您ImageSource在非 UI 线程上创建。除非您冻结对象,否则您无法执行此操作。您将希望所有与 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 线程上。

于 2013-01-10T05:51:43.110 回答