2010-11-24 68 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

相关问题