2010-09-13 145 views
1

我有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

回答

0

我不知道在哪裏可以添加,但我想通張貼作爲一個答案是更好,因爲它排序什麼,我要怎樣做。

我所做的是爲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同時創建所有四個集合,而不是一個接一個地創建它們以提高加載時間。