Как загрузить элементы комбинированного списка при загрузке окна - PullRequest
1 голос
/ 13 сентября 2010

У меня есть 4 комбинированных списка (через наблюдаемую коллекцию) с 4 отдельными папками, содержащими около 200+ предметов в каждой.Когда окно загружается впервые, имена файлов сохраняются в 4 отдельных наблюдаемых коллекциях, текст данных каждого комбинированного списка устанавливается в соответствующую коллекцию, затем я использую конвертер для преобразования URI в изображение (с уменьшенным качеством для улучшения загрузкинемного) внутри ItemTemplate.

Когда я запускаю проект, заставка появляется в течение 2-3 секунд макс.Но когда я пытаюсь открыть каждый выпадающий список, загрузка всех элементов занимает 20-30 секунд.Поэтому мне интересно, как я могу переместить эту загрузку в то время, когда отображается заставка.

В качестве альтернативы, есть ли способ сделать что-то до / во время загрузки списка элементов, чтобы сообщить пользователю приложениене замерз?.. В комбинированном ящике используется обертка, поэтому я добавил событие Loaded, чтобы поменять метку на «Готово» после завершения загрузки, но я не знаю, какое событие использовать, чтобы сообщить пользователю, что он начал загрузку.Я пытался использовать 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 голосов
/ 14 сентября 2010

Я не знал, где добавить это, но я решил, что опубликовать его как ответ лучше, потому что он сортирует то, что я пытался сделать.

Что я сделал, так это добавил новое свойство 'Image' (типа BitmapImage) для класса CustomLayer; поэтому миниатюра теперь фактически является частью объекта 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 ComboBox, следующая строка:

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

изменено на это:

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

Теперь фактическое создание миниатюр происходит во время загрузки окна, и когда пользователь нажимает на поле со списком в первый раз, оно загружается довольно быстро!

Теперь, чтобы понять, как я могу использовать BackgroundWorker для создания всех четырех коллекций одновременно, а не создавать их одну за другой, чтобы сократить время загрузки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...