如何在窗口加载时加载组合框项目

问题描述:

我有4个组合框(通过可观察集合)绑定到4个独立的文件夹,每个文件夹包含大约200多个项目。当窗口第一次加载时,文件名存储在4个独立的可观察集合中,每个组合框的datacontext被设置为其各自的集合,然后我使用转换器将uri转换为图像(降低质量以改进加载位)在ItemTemplate内。如何在窗口加载时加载组合框项目

当我运行该项目时,启动画面最多显示2-3秒。但是当我尝试打开每个组合框时,需要20-30秒才能第一次加载所有项目。所以我想知道如何在显示启动画面时将此加载移动到。

或者,在组合框正在加载其项目以让用户知道应用程序未冻结之前,有没有办法执行某些操作? .. ComboBox正在使用一个wrappanel,因此我添加了一个Loaded事件来在完成加载时将标签更改为“完成”,但我不知道使用哪个事件来告诉用户它已开始加载。我在组合框上尝试了MouseDown,但这并没有帮助(我认为即使它工作正常也不会给出正确的行为)。

编辑:下面的代码(只是复制了相关部分的一个组合框简洁)

主窗口,组合框XAML:

<Window.Resources> 
    <local:UriToThumbnailConverter x:Key="myThumbnailConverter" /> 
</Window.Resources> 
    <ComboBox Height="Auto" Width="Auto" x:Name="cmbLayers1" ItemsSource="{Binding}"> 
        <ComboBox.ItemTemplate> 
         <DataTemplate> 
          <Border Margin="3,8"> 
           <Image Source="{Binding Path=FullPath, Converter={StaticResource myThumbnailConverter}}" Height="60"> 
            <Image.ToolTip> 
              <TextBlock Text="{Binding Path=Name}"/> 
            </Image.ToolTip> 
           </Image> 
           <Border.Background> 
            <ImageBrush ImageSource="/WpfMyApplication;component/Images/ThumbnailBackground.png" Stretch="Uniform" TileMode="None" /> 
           </Border.Background> 
          </Border> 
         </DataTemplate> 
        </ComboBox.ItemTemplate> 
        <ComboBox.ItemsPanel> 
         <ItemsPanelTemplate> 
          <WrapPanel /> 
         </ItemsPanelTemplate> 
        </ComboBox.ItemsPanel> 
    </ComboBox> 

主窗口隐藏代码:

Private layers1 As New ObservableCollection(Of CustomLayer) 

Sub New() 

    InitializeComponent() 

    cmbLayers1.DataContext = layers1 

    ImportLayersFromFolder(My.Application.Info.DirectoryPath & "\Layer1", layers1) 
    cmbLayers1.SelectedIndex = 0 

End Sub 

Private Sub ImportLayersFromFolder(ByVal folder As String, ByVal layers As ObservableCollection(Of CustomLayer)) 
     Dim files() As String = Directory.GetFiles(folder, "*.png") 

     Try 
      For Each sFile As String In files 
       layers.Add(New CustomLayer(sFile)) 
      Next 
     Catch ex As Exception 
      MessageBox.Show(ex.Message) 
     End Try 
End Sub 

CustomLayer种类:

Public Class mainLayer 

Public Property Name As String 
Public Property Path As String 
Public ReadOnly Property FullPath As String 
    Get 
     Return System.IO.Path.Combine(Path, Name) 
    End Get 
End Property 

Public Overrides Function ToString() As String 
    Return FullPath 
End Function 


Public Sub New(ByVal filename As String) 
    Dim info As New FileInfo(filename) 
    Name = info.Name 
    Path = info.DirectoryName 
End Sub 

End Class 

缩略图转换器:

Public Class UriToThumbnailConverter 
Implements IValueConverter 

Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert 
    Dim bi As New BitmapImage() 

    bi.BeginInit() 
    bi.DecodePixelWidth = 60 
    bi.CacheOption = BitmapCacheOption.OnLoad 
    bi.UriSource = New Uri(value.ToString()) 
    bi.EndInit() 
    Return bi 

End Function 

Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack 
    Throw New NotSupportedException 
End Function 
End Class 
+0

是否需要很长时间才能将ObservableCollection数据检索到集合中,还是需要很长时间才能显示数据? – Robaticus 2010-09-13 15:16:27

+0

我怀疑显示实际图像需要很长时间,因为它们可能会在飞行中加载。但是,没有看到一些代码,这都是猜测。 – 2010-09-13 15:51:37

+0

我已经添加了一些代码,请参阅编辑的帖子。 当用户打开组合框(仅限第一次)时,创建缩略图/图像需要很长时间,而不是创建ObservableCollection时创建缩略图/图像,因为这是在初始化时发生的,并且启动画面仅在2-3秒内才可见,然后窗口显示出来(每个组合框中的第一项被选中)。 – Mike 2010-09-13 16:35:22

我不知道在哪里可以添加,但我想通张贴作为一个答案是更好,因为它排序什么,我要怎样做。

我所做的是为CustomLayer类添加一个新的'Image'属性(类型为BitmapImage);所以缩略图现在实际上是CustomLayer对象的一部分。

在CustomLayer类新的构建,现在看起来是这样的:

Public Sub New(ByVal filename As String) 

    Dim info As New FileInfo(filename) 
    Name = info.Name 
    Path = info.DirectoryName 

    Dim bi As New BitmapImage() 

    bi.BeginInit() 
    bi.DecodePixelWidth = 60 
    bi.CacheOption = BitmapCacheOption.OnLoad 
    bi.UriSource = New Uri(FullPath) 
    bi.EndInit() 

    Image = bi 

End Sub 

此外,组合框的ItemTemplate中,以下行内:

<Image Source="{Binding Path=FullPath, Converter={StaticResource myThumbnailConverter}}" Height="60"> 

改成这样:

<Image Source="{Binding Path=Image}" Height="60"> 

现在,缩略图的实际创建是在窗口加载时发生的,而当用户第一次点击组合框,它会很快加载!

现在想出如何使用BackgroundWorker同时创建所有四个集合,而不是一个接一个地创建它们以提高加载时间。