1

我有一個列表框,它綁定到一個簡單對象列表。我們知道默認的列表框有它的項目主機作爲一個StackPanel,所以它以這種方式勾畫出項目如何在Silverlight中獲取此類型的佈局?

item1 
item2 
item3 
item4 
item5 
item6 

但是我有一些條件,通過它我檢查的項目是否可以水平或垂直顯示和因此項目可以以這種方式

如進行佈局: -

item1 
item2 
item3 item4 item 5 
item6 

怎麼可能做到這一點? (如果你想知道爲什麼我會需要這樣的事情,一個示例場景將是「臉譜風格更新」,如果用戶不斷地上傳3-4張照片,他們並不總是出現在下一行,但它可能會出現水平,而如果他的職位出現在下一行的一些事件)提前:)

回答

1

解決方案的fundementals在使用另一種ItemsControlListBoxItemTemplate。這ItemsControl應該有一個水平面向StackPanel作爲其ItemsPanel

這裏是一個基本的例子。讓我們先從一些很簡單的TESTDATA: -

public class TestStringList : List<string> 
{ 
    public TestStringList() 
    { 
     AddRange(new[] {"Anthony", "Kar", "Martin", "Jon", "Erik", "Darin", 
      "Balus", "Mike", "Hans", "Alex", "Anomie", "David" }); 

    } 
} 

現在,我們希望在一個列表框來顯示這個列表,但保留所有具有在同一行同一首字母的名字。我將使用IValueConverter的實現來處理我們需要的分組。如果您使用的是MVVM,那麼您可以使用ViewModel。

public class Grouper : IValueConverter 
{ 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return ((IEnumerable<string>)value).OrderBy(s => s).GroupBy(s => s[0]); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

該轉換器的輸出基本上是IEnumerable<IEnumerable<string>>這就是我們想要的。外部列表框將枚舉外部集合,並且內部ItemsControl將枚舉內部集合的字符串,這將是具有相同初始值的一組名稱。

這裏是XAML: -

<UserControl x:Class="SilverlightApplication1.SimpleGrouping" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:SilverlightApplication1" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400"> 

    <UserControl.Resources> 
     <local:TestStringList x:Key="TestData" /> 
     <local:Grouper x:Key="grouper" /> 
    </UserControl.Resources> 

    <Grid x:Name="LayoutRoot"> 
     <ListBox ItemsSource="{Binding Converter={StaticResource grouper}, Source={StaticResource TestData}}"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <ItemsControl ItemsSource="{Binding}"> 
         <ItemsControl.ItemsPanel> 
          <ItemsPanelTemplate> 
           <StackPanel Orientation="Horizontal" /> 
          </ItemsPanelTemplate> 
         </ItemsControl.ItemsPanel> 
         <ItemsControl.ItemTemplate> 
          <DataTemplate> 
           <TextBlock Text="{Binding}" Margin="5" /> 
          </DataTemplate> 
         </ItemsControl.ItemTemplate> 
        </ItemsControl> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
    </Grid> 
</UserControl> 
4

感謝如果使用MVVM pattern我會做這樣的事情:

  1. 創建一個視圖模型查看您的列表框所在。此VM包含ns集合ListItemViewModel實例(請參閱下一點)
  2. 創建一個名爲ListItemViewModel的ViewModel(根據您的域名給它一個更合適的名稱)。此視圖模型包含一個ItemViewModel實例的集合(請參閱下一點)。
  3. 創建一個名爲ItemViewModel的ViewModel。這些中的每一個都支持列表中的單個項目。根據你的域名給這個更合適的名字。
  4. 創建一個包含您的列表框的視圖。將您的列表框綁定到VM中的ListItemViewModels集合。這個列表框的項目模板將是一個ListItemView(見下一點)。項目面板模板將成爲默認的StackPanel。
  5. 創建一個具有ListItemViewModel數據上下文的ListItemView。這個視圖由一個ItemViews的水平StackPanel組成(見下一點)。
  6. 創建一個由ItemViewModel支持的ItemView。

您的視圖看起來像這樣,每個視圖都有相應的ViewModel。

就像我上面說的,你一定會想改變你的意見/視圖模型的名字,我的是僅用於演示目的:)

+0

真的很好:)。投票! – TCM 2011-03-24 18:03:01