2014-02-28 24 views
0

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

我试着添加一个VirtualizingStackPanel,没有任何可见的变化,还有很多,最后从一个非常基本的示例构建了一个新程序,见下文。这会立即显示内容,同样当我应用大小转换器时,但我绝不会将它在多列中显示出来!看起来微软的例子通过将WrapPanel添加到一个定位列表框的样式来完成这一工作,而行IsItemsHost =“True”显然对于获取多列图像至关重要。当我在我的示例中(在PhotoListBoxStyle中)尝试相同的功能时,程序甚至不再启动。当我重建程序作为微软的例子,但保留代码来安排绑定,它仍然很快,但是resizer停止正常工作,它仍然使用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; 
     } 
    } 
} 

回答

0

如果你想换的ListBox内容,那么你需要改变ListBox.ItemsPanel,它承载的所有项目,要WrapPanel然后您的ItemTemplate将只是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> 

StackPanelVirtualizingStackPanel将永远不会包装内容。它将水平或垂直堆叠子项目。

编辑

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

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

+0

感谢您的回复,dkozi,但不幸的是它不起作用。它已经尝试过,但确实是我发布的XAML -Listbox样式 - 没有WrapPanel。当我将XAML替换为你的时候,我仍然有1列(当我添加IsItemsHost =“True”时),并且图像不再像以前那样调整大小,只有质量被恢复。还有什么想法?我还想知道为什么样本速度如此之快(即时显示2500张图片)而没有任何虚拟化; MSDN示例要慢得多 - 有或没有虚拟化。 Dick – Dick

+0

你的意思是_aren't resized_?你也想水平或垂直包装它?在其他工作中,你想看垂直滚动条还是水平? – dkozl

+0

1我希望它双向包裹,水平直到行已满,然后垂直。现在只有1列。 2使用我的原始XAML,UriToBitmapConverter(请参阅代码)将显示的图像大小调整为代码中的大小(bi.DecodePixelWidth 100 =小缩略图)。使用XAML,图像以原始大尺寸显示,但质量非常低(当增加数值时图像会增加)Dick – Dick