如何将大量图像添加到列表框中

时间:2012-12-21 10:51:44

标签: c# windows-phone-7 windows-phone-7.1

我正在为Windows Phone 7制作这个应用程序,我所做的是从相机胶卷,保存的图片和其他文件夹中检索所有图像,并将它们显示在包装面板内的列表框中,以便它们并排显示... 。实际显示图像的缩略图听..... 但随着图像数量的增加,UI变得非常慢,滚动需要时间......

我读了许多帖子和其他问题我认为数据虚拟化或延迟加载是我需要的但我不明白我怎么能用它,我看到了来自shawn oster和peter torr的帖子......

我使用backgroundworker加载图片...... 这是怎么......

 void backroungWorker1_DoWork(object sender, DoWorkEventArgs e)
    {

        Dispatcher.BeginInvoke(() =>
        {
            foreach (string fileName in fileStorage.GetFileNames("images//*.*"))
            {
                if (fileName == null)
                    break;
                string filepath = System.IO.Path.Combine("images", fileName);
                try
                {
                    using (IsolatedStorageFileStream imageStream = fileStorage.OpenFile(filepath, FileMode.Open))
                    {
                        var imageSource = PictureDecoder.DecodeJpeg(imageStream);
                        BitmapImage bitmapImage = new BitmapImage();
                        bitmapImage.SetSource(imageStream);
                        var item = new ImageToName { bmp = bitmapImage, FileName = fileName };
                        vltBitmapImage.Add(item);
                        imageStream.Dispose();
                        imageStream.Close();
                    }
                }
                catch
                {
                    Exception x = new Exception();
                }
            }
            if (vltBitmapImage.Count() != 0)
            {
                lone.Visibility = Visibility.Collapsed;
                this.vaultbox.ItemsSource = vltBitmapImage;
            }
            else
                lone.Visibility = Visibility.Visible;
        });
    }

任何帮助都非常感谢..... 对不起是一个菜鸟......

2 个答案:

答案 0 :(得分:0)

从代码项目中尝试此示例,它解释了它是如何工作的,并附带一个完整的示例项目

请参阅:Loading Data when the User scrolls to the end of the list

答案 1 :(得分:0)

如果要将Lazy加载添加到列表框,则必须为列表框设置列表器并更改将数据加载到数据模型中的方式,因此首先要在XAML代码中设置列表框:

在您的页面资源中添加此样式,并记下其包含的已加载事件(“ScrollViewer_Loaded”):

...
  <phone:PhoneApplicationPage.Resources>
    <Style x:Key="BusinessListBoxStyle"
           TargetType="ListBox">
        <Setter Property="Background"
                Value="Transparent" />
        <Setter Property="Foreground"
                Value="{StaticResource PhoneForegroundBrush}" />
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility"
                Value="Disabled" />
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility"
                Value="Auto" />
        <Setter Property="BorderThickness"
                Value="0" />
        <Setter Property="BorderBrush"
                Value="Transparent" />
        <Setter Property="Padding"
                Value="0" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBox">
                    <ScrollViewer x:Name="scrollViewer"
                                  BorderBrush="{TemplateBinding BorderBrush}"
                                  BorderThickness="{TemplateBinding BorderThickness}"
                                  Background="{TemplateBinding Background}"
                                  Foreground="{TemplateBinding Foreground}"
                                  Padding="{TemplateBinding Padding}"
                                  Loaded="ScrollViewer_Loaded">
                        <ItemsPresenter />
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</phone:PhoneApplicationPage.Resources>

...

为列表框添加对样式的引用,并将itemsSource绑定到viewModel中的项目列表。

...
        <ListBox x:Name="myList"
                 ItemsSource="{Binding myDataSource}"
                 Style="{StaticResource BusinessListBoxStyle}">

...

接下来,当您到达列表中list元素的末尾时,必须设置一些将数据加载到datamodel中的代码(datamodel开始将更多数据加载到模式中,添加更多项目)Lazyloading !!

我正常做的方法是列出列表框滚动条的垂直偏移量,如果距离边缘约1/4,我开始将更多项加载到数据模型中。 在ScrollViewer加载的处理程序中,我在VertialOffset监听器中设置,使用DependencyProperty,请参阅下面的代码:

        public static readonly DependencyProperty ListVerticalOffsetProperty =
        DependencyProperty.Register(
                                    "ListVerticalOffset",
                                    typeof(double),
                                    typeof(MyPage),
                                    new PropertyMetadata(new PropertyChangedCallback(OnListVerticalOffsetChanged))
                                    );

    private ScrollViewer _listScrollViewer;

    private void ScrollViewer_Loaded(object sender, RoutedEventArgs e)
    {
        _listScrollViewer = sender as ScrollViewer;

        Binding binding = new Binding();
        binding.Source = _listScrollViewer;
        binding.Path = new PropertyPath("VerticalOffset");
        binding.Mode = BindingMode.OneWay;
        this.SetBinding(ListVerticalOffsetProperty, binding);
    }

    public double ListVerticalOffset
    {
        get { return (double)this.GetValue(ListVerticalOffsetProperty); }
        set { this.SetValue(ListVerticalOffsetProperty, value); }
    }

    private double _lastFetch;

    private static void OnListVerticalOffsetChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        MyPage page = obj as MyPage;
        ScrollViewer viewer = page._listScrollViewer;

        if (viewer != null)
        {
            if (page._lastFetch < viewer.ScrollableHeight)
            {
                // Trigger within 1/4 the viewport.
                if (viewer.VerticalOffset >= (viewer.ScrollableHeight - (viewer.ViewportHeight / 4)))
                {
                    page._lastFetch = viewer.ScrollableHeight;
                    MyViewModel _tmpviewmodel = page.DataContext as MyViewModel;

                    if ((_tmpviewmodel != null) && (_tmpviewmodel.HasMoreItems))
                        _tmpviewmodel.GetMoreItems();
                }
            }
        }
    }

请注意,我使用MyViewModel,它包含列表框绑定到的所有项目,并具有从数据库,隔离库,Web或您需要的任何内容加载项目的方法。

您必须找到仅将部分数据加载到viewmodel中的方法。我是你的情况我将首先加载你需要加载的所有文件的列表(这只是从IsoLatedStore中的GetFileNames中检索列表)。然后mayby当时只加载了20张照片!