2010-11-24 72 views
6

首先,here是以前的帖子,它處理ListBox AccountListBox數據綁定到我的ObservableCollection<Account>帳戶從AccountsCollection.cs類。如何通過使用XAML的WPF中的第一個字母來組合ListBoxItems?

所以現在我有一個綁定對象AccountsCollection和一個名爲AccountTemplate在資源定義我的ListBox的DataTemplate:

​​

,這裏是有關LisBox本身的代碼:

<ListBox Name="AccountsListBox" 
     Margin="12,38,12,41" 
     HorizontalContentAlignment="Stretch" 
     ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
     ItemsSource="{Binding Accounts, 
      Source={StaticResource ResourceKey=AccountsCollection}}" 
     ItemTemplate="{StaticResource ResourceKey=AccountTemplate}" 
     MouseDoubleClick="AccountsListBox_MouseDoubleClick"> 
</ListBox> 

我希望我的清單可以設計爲通過開始信件將所有帳戶分組,並在清單中顯示該信件(另外我想對信件標題應用一些設計)。最終的結果應該是這樣的:

alt text

感謝所有幫助!

更新:以下是成功實施分組的代碼。

<Window x:Class="Gui.Wpf.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:entities="clr-namespace:Entities.Accounts;assembly=Entities" 
    xmlns:contollers="clr-namespace:Gui.Wpf.Controllers" 
    xmlns:converters="clr-namespace:Gui.Wpf.Converters" 
    xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase" 
    Title="MainWindow" 
    Width="525" 
    Height="350" > 

<Window.Resources> 

    <!-- Main window controller --> 
    <contollers:MainWindowController 
     x:Key="MainWindowController" /> 

    <!-- Converter for first letter extraction from the account name --> 
    <converters:FirstLetterConverter x:Key="FirstLetterConv" /> 

    <!-- View source for the AccountsListBox --> 
    <CollectionViewSource 
     x:Key="AccountsView" 
     Source="{Binding Accounts, Source={StaticResource ResourceKey=MainWindowController}}"> 

     <!-- Sorting --> 
     <CollectionViewSource.SortDescriptions> 
      <componentModel:SortDescription PropertyName="AccountName" /> 
     </CollectionViewSource.SortDescriptions> 

     <!-- Grouping --> 
     <CollectionViewSource.GroupDescriptions> 
      <PropertyGroupDescription PropertyName="AccountName" Converter="{StaticResource ResourceKey=FirstLetterConv}" /> 
     </CollectionViewSource.GroupDescriptions> 

    </CollectionViewSource> 

    <!-- Data template for the type Account --> 
    <DataTemplate 
     DataType="{x:Type entities:Account}"> 
     <DockPanel> 
      <Button 
       Name="DeleteButton" 
       DockPanel.Dock="Right" 
       Margin="3, 1, 3, 1" 
       VerticalAlignment="Center" 
       Content="Delete" /> 
      <Button 
       Name="EditButton" 
       DockPanel.Dock="Right" 
       Margin="3, 1, 3, 1" 
       VerticalAlignment="Center" 
       Content="Edit" /> 
      <TextBlock 
       Name="AccountNameTextBlock" 
       VerticalAlignment="Center" 
       Text="{Binding AccountName}" 
       TextWrapping="NoWrap" 
       TextTrimming="CharacterEllipsis" /> 
     </DockPanel> 

    </DataTemplate> 

    <!-- Data template for AccountListBox grouping --> 
    <DataTemplate x:Key="GroupingHeader"> 
     <TextBlock Text="{Binding Path=Name}" Background="Black" Foreground="White" /> 
    </DataTemplate> 

</Window.Resources> 

<Grid> 
    <ListBox 
     Name="AccountsListBox" 
     Width="300" 
     Height="200" 
     HorizontalAlignment="Center" 
     VerticalAlignment="Center" 
     ItemsSource="{Binding Source={StaticResource ResourceKey=AccountsView}}" 
     HorizontalContentAlignment="Stretch" > 
     <ListBox.GroupStyle> 
      <GroupStyle 
       HeaderTemplate="{StaticResource ResourceKey=GroupingHeader}" /> 
     </ListBox.GroupStyle> 
    </ListBox> 
</Grid> 

回答

13

您可以使用CollectionViewSource和轉換器提取的第一個字母:

<local:FirstLetterConverter x:Key="firstLetterConverter" /> 

<CollectionViewSource x:Key="cvs" Source="{Binding Accounts, Source={StaticResource AccountsCollection}}"> 
    <CollectionViewSource.SortDescriptions> 
     <scm:SortDescription PropertyName="AccountName" /> 
    </CollectionViewSource.SortDescriptions> 
    <CollectionViewSource.GroupDescriptions> 
     <PropertyGroupDescription PropertyName="AccountName" Converter="{StaticResource firstLetterConverter}" /> 
    </CollectionViewSource.GroupDescriptions> 
</CollectionViewSource> 

... 

<ItemsControl ItemsSource="{Binding Source={StaticResource cvs}}"> 
    ... 

轉換器:

public class FirstLetterConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     string s = value as string; 
     if (s != null && s.Length > 0) 
      return s.Substring(0, 1); 
     return string.Empty; 
    } 

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

如果你想一個樣式應用到組,您可以使用GroupStyle屬性:

... 
    <ItemsControl.GroupStyle> 
    <GroupStyle> 
     <GroupStyle.HeaderTemplate> 
     <DataTemplate> 
      <TextBlock FontWeight="Bold" FontSize="15" Text="{Binding Path=Name}" /> 
     </DataTemplate> 
     </GroupStyle.HeaderTemplate> 
     <GroupStyle.ContainerStyle> 
     <Style TargetType="{x:Type GroupItem}"> 
      <Setter Property="Background" Value="Gray" /> 
      <Setter Property="Foreground" Value="White" /> 
     </Style> 
     </GroupStyle.ContainerStyle> 
    </GroupStyle> 
    </ItemsControl.GroupStyle> 
    ... 
2

這裏是一個解決方案的一個例子,這是非常相似的:

首先,我們需要生成一個更好地收集你的DataContext - 這裏的,你可以很容易地修改一個例子您目的 -

public Window1() 
{ 
    InitializeComponent(); 
    var s = new[] { "Dave", "Adam", "Jeny", "Nick", "James" }; 
    DataContext = s 
     .Select(n => n[0]) 
     .Distinct() 
     .ToDictionary(l => l.ToString(), l => s 
      .Where(w => w 
       .StartsWith(l.ToString()))); 
} 

那麼我們只需要嵌套ItemsControls的UI -

<ItemsControl ItemsSource="{Binding}"> 
<ItemsControl.ItemTemplate> 
    <DataTemplate> 
    <StackPanel> 
     <TextBlock Foreground="Red" Text="{Binding Key}" FontSize="12" Margin="5" /> 
     <ItemsControl ItemsSource="{Binding Value}"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
      <StackPanel Orientation="Horizontal" Margin="5"> 
       <Button Content ="View" Margin="0,0,5,0" /> 
       <Button Content ="Delete" Margin="0,0,5,0" /> 
       <TextBlock Text="{Binding}" /> 
      </StackPanel> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </StackPanel> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 

,我們得到這樣的:

alt text

+0

感謝您的答覆。當談到LINQ時,我無能爲力;你可以解釋一下: DataContext = s.Select(n => n [0])。Distinct()。ToDictionary(l => l.ToString(),l => s.Where(w => w .StartsWith(l.ToString()))); 我不是說你把它轉換成某種東西,我只是非常感謝你能用簡單的英語來描述那裏發生了什麼:)謝謝! – Boris 2010-11-24 12:25:07

+0

linq正在做的事情是: 1)創建所有正在使用的前綴字符的列表('D','A','J','N') 2)創建一個Dictionary >關鍵是前綴,可枚舉是所有匹配前綴的字符串 您可以使用foreach循環等來做同樣的事情 – 2010-11-24 12:51:58

相關問題