Horizontal stretch list item in WP7 with grouping
I want to implement ListBox Grouping on WP7. I found this article is very useful. Actually I made the grouping works. But I got a problem with ListItem horizontal stretch. I guess I need to set ItemContainerStyle and change HorizontalContentAlignment as Stretch. But it doesn't work for this case (if set the ItemTemplate directly, it works). Any suggestions? Thanks a lot!
Here is the code, the ListItem is supposed to be stretched, but it's centered instead.
C#:
public class GroupingItemsControlConverter : IValueConverter
{
public object Convert(object value, Type tagetType, object parameter, CultureInfo culture)
{
var valueAsIEnumerable = value as IEnumerable;
if (null == valueAsIEnumerable)
{
throw new ArgumentEx开发者_如何学Goception("GroupingItemsControlConverter works for only IEnumerable inputs.", "value");
}
var parameterAsGroupingItemsControlConverterParameter = parameter as GroupingItemsControlConverterParameters;
if (null == parameterAsGroupingItemsControlConverterParameter)
{
throw new ArgumentException("Missing required GroupingItemsControlConverterParameter.", "parameter");
}
var groupSelectorAsIGroupingItemsControlConverterSelector = parameterAsGroupingItemsControlConverterParameter.GroupSelector as IGroupingItemsControlConverterSelector;
if (null == groupSelectorAsIGroupingItemsControlConverterSelector)
{
throw new ArgumentException("GroupingItemsControlConverterParameter.GroupSelector must be non-null and implement IGroupingItemsControlConverterSelector.", "parameter");
}
// Return the grouped results
return ConvertAndGroupSequence(valueAsIEnumerable.Cast<object>(), parameterAsGroupingItemsControlConverterParameter);
}
private IEnumerable<object> ConvertAndGroupSequence(IEnumerable<object> sequence, GroupingItemsControlConverterParameters parameters)
{
// Validate parameters
var groupKeySelector = ((IGroupingItemsControlConverterSelector)(parameters.GroupSelector)).GetGroupKeySelector();
var orderKeySelector = ((IGroupingItemsControlConverterSelector)(parameters.GroupSelector)).GetOrderKeySelector();
if (null == groupKeySelector)
{
throw new NotSupportedException("IGroupingItemsControlConverterSelector.GetGroupSelector must return a non-null value.");
}
// Do the grouping and ordering
var groupedOrderedSequence = sequence.GroupBy(groupKeySelector).OrderBy(orderKeySelector);
// Return the wrapped results
foreach (var group in groupedOrderedSequence)
{
yield return new ContentControl { Content = group.Key, ContentTemplate = parameters.GroupStyle };
foreach (var item in group)
{
yield return new ContentControl { Content = item, ContentTemplate = parameters.ItemStyle };
}
}
}
public object ConvertBack(object value, Type tagetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException("GroupingItemsControlConverter does not support ConvertBack.");
}
}
public class GroupingItemsControlConverterParameters
{
public DataTemplate GroupStyle { get; set; }
public DataTemplate ItemStyle { get; set; }
public IGroupingItemsControlConverterSelector GroupSelector { get; set; }
};
public abstract class IGroupingItemsControlConverterSelector
{
public abstract Func<object, IComparable> GetGroupKeySelector();
public virtual Func<IGrouping<IComparable, object>, IComparable> GetOrderKeySelector() { return g => g.Key; }
}
public class GroupingItemsControlConverterSelector : IGroupingItemsControlConverterSelector
{
public override Func<object, IComparable> GetGroupKeySelector()
{
return (o) => (o as ItemViewModel).Group;
}
}
XAML:
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.Resources>
<DataTemplate x:Key="GroupHeaderTemplate">
<Border BorderBrush="Yellow" BorderThickness="1" Margin="12,3,12,12" Padding="6" VerticalAlignment="Center">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Number}" HorizontalAlignment="Left" Margin="6,0,0,0" FontSize="22" Foreground="White"/>
<TextBlock Grid.Column="1" Text="{Binding Name}" HorizontalAlignment="Right" Margin="0,0,6,0" FontSize="22" Foreground="White"/>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="CustomItemTemplate">
<Grid Margin="12,3,12,12" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="{Binding Number}" HorizontalAlignment="Left" Margin="6,0,0,0" FontSize="22" Foreground="White"/>
<TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Name}" HorizontalAlignment="Right" Margin="0,0,6,0" FontSize="22" Foreground="White"/>
</Grid>
</DataTemplate>
<local:GroupingItemsControlConverter x:Key="GroupingItemsConverter" />
<local:GroupingItemsControlConverterSelector x:Key="GroupingItemsSelector" />
<local:GroupingItemsControlConverterParameters x:Key="GroupingItemParameters"
GroupStyle="{StaticResource GroupHeaderTemplate}"
ItemStyle="{StaticResource CustomItemTemplate}"
GroupSelector="{StaticResource GroupingItemsSelector}"
/>
<Style TargetType="ListBoxItem" x:Key="CustomItemContainerStyle">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</Grid.Resources>
<ListBox x:Name="TheListBox"
ItemsSource="{Binding Items, Converter={StaticResource GroupingItemsConverter}, ConverterParameter={StaticResource GroupingItemParameters}}"
ItemContainerStyle="{StaticResource CustomItemContainerStyle}" />
</Grid>
ListBox grouping? You should consider using the LongListSelector from the Silverlight Toolkit. And to simplify the binding for that, you can use the LongListCollection collection type (Check the entire example, for details).
Then you can simply create apps that groups values, for example like this:
精彩评论