0

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

我阅读了很多帖子和其他问题,我认为数据虚拟化或延迟加载是我需要的,但我不明白如何使用它,我看到了 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;
        });
    }

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

4

2 回答 2

0

If you want to add a Lazy load to a listbox you must setup a listner for your list box and change the way you load data into your data model, so first lest set up at the XAML code for a listbox:

In your page resource add this style, and note the loaded event its include ("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>

...

The add a reference to your style for the listbox, and bind your itemsSource to a list of items from your viewModel.

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

...

Next you have to set some code that loads data into the datamodel, when you reach the end of the list element in the list (the datamodel start loading more data into the mode, adds more items) Lazyloading!!

The way i normaly do this is by listing to the vertical offset of the listbox's scrollbar, and if its is about 1/4 from the edge i starts loading more items into the datamodel. In the ScrollViewer loaded handler i set up at VertialOffset listener, by using the DependencyProperty, see code below:

        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();
                }
            }
        }
    }

Note here i make use of a MyViewModel, that holds all the items the listbox i binded to, and has methods for load items from a database, the isolatedstore, the web or what ever your needs are.

You just have to find your way of only load a part of your data into the viewmodel. I your case i will first load a list of all the files you need to load (that is just to retreive the list from GetFileNames in the IsoLatedStore). Then mayby only loads 20 pics at the time!

于 2013-01-11T09:25:07.487 回答
0

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

请参阅:当用户滚动到列表末尾时加载数据

于 2013-01-10T21:35:09.990 回答