WPF列表框不会显示包含在多列中的图像

时间:2014-02-28 20:45:28

标签: wpf image listbox multiple-columns

我正在尝试获取目录的内容,其中包含许多图像显示在列表框中,水平包裹内容,显示小图片和可调整大小。 http://msdn.microsoft.com/en-us/library/ms771331%28v=vs.85%29.aspx上有一个样本正在这样做,但是我需要动态填充2500张图片需要10秒钟,而且它使用的缩略图似乎并不总是存储在图像中。

我尝试添加VirtualizingStackPanel,没有任何明显的变化,还有更多,最后从一个非常基本的样本中构建了一个新程序,见下文。这显示了内容,当我应用尺寸转换器时也是如此,但我绝不能在多列中获取它!似乎微软的例子是通过向一个以列表框为目标的样式添加WrapPanel来完成此操作,并且线IsItemsHost =“True”显然对于将图像放在多个列中至关重要。当我在我的样本中尝试相同时(在PhotoListBoxStyle中),程序甚至不再启动。当我重建程序作为Microsoft示例但保留代码以安排绑定时,它仍然很快,但调整器停止正常工作,它仍然使用1列。

如何将以下代码包装在多个列中?

迪克

XAML:

<Window x:Class="PhotoData.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:PhotoData"       
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <local:UriToBitmapConverter x:Key="UriToBitmapConverter" />
        <!-- Main photo catalog view -->
        <Style TargetType="{x:Type ListBox}" x:Key="PhotoListBoxStyle">
            <Setter Property="Foreground" Value="White" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBox}" >
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>


    <GroupBox Grid.Column="0" Grid.Row="1">

        <ListBox Margin="10" Name="designerListBox"  >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal"
                       VerticalAlignment="Center"
                       HorizontalAlignment="Center"
                       IsItemsHost="True">
                        <Image Source="{Binding imageLocation, Converter={StaticResource UriToBitmapConverter}}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </GroupBox>

</Window>

代码背后:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;


namespace PhotoData
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            List<binderClass> myList = new List<binderClass>();

            foreach (string file in Directory.GetFiles(@"c:\temp", "*.jpg", SearchOption.AllDirectories))
            {
                myList.Add(new binderClass() { imageLocation = file, displayName = "TEST" });
                Debug.WriteLine(file);

            }

            designerListBox.ItemsSource = myList;
        }
    }

    public class UriToBitmapConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.DecodePixelWidth = 100;
            bi.CacheOption = BitmapCacheOption.OnLoad;
            bi.UriSource = new Uri(value.ToString());
            bi.EndInit();
            return bi;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
    class binderClass
    {
        public string imageLocation
        {
            get;
            set;
        }
        public string displayName
        {
            get;
            set;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果您要打包ListBox的内容,则需要将托管所有项目的ListBox.ItemsPanel更改为WrapPanel,然后ItemTemplate将{ {1}}:

Image

<ListBox Name="designerListBox" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate> <Image Width="100" Source="{Binding imageLocation, Converter={StaticResource UriToBitmapConverter}}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox> StackPanel永远不会包含内容。它将水平或垂直堆叠子项。

修改

使用与VirtualizingStackPanel不同的面板时,您可能遇到一些性能问题,尤其是在处理图像时。其他面板不提供虚拟化,因此所有项目都被视为可见,并将立即加载。

  

标准布局系统创建项容器并计算与列表控件关联的每个项的布局。词语“虚拟化”指的是一种技术,通过该技术,基于哪些项目在屏幕上可见,从大量数据项生成用户界面(UI)元素的子集。当屏幕上只有少数元素可能会生成许多UI元素时,会对应用程序的性能产生负面影响。 VirtualizingStackPanel计算可见项的数量,并使用ItemsControl(例如ListBox或ListView)中的ItemContainerGenerator来为可见项创建UI元素。