2014-02-28 61 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