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

时间:2010-09-13 15:09:48

标签: wpf combobox load

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

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

或者,有没有办法在组合框加载项目之前/同时做一些事情让用户知道应用程序没有冻结? ..组合框正在使用一个wrappanel,所以我添加了一个Loaded事件,以便在完成加载时将标签更改为“Done”,但我不知道用哪个事件告诉用户它已开始加载。我在组合框上尝试了MouseDown,但这没有帮助(我认为它不会给出正确的行为,即使它有效)。

编辑:这是代码(为简单起见,只复制一个组合框的相关部分)

MainWindow,ComboBox 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>

MainWindow代码隐藏:

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

1 个答案:

答案 0 :(得分: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

此外,在ComboBox的ItemTemplate中,包含以下行:

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

改为:

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

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

现在要弄清楚如何使用BackgroundWorker同时创建所有四个集合,而不是一个接一个地创建它们以改善加载时间。