在ItemsControl或ListView中,是否可以使GroupStyle.HeaderTemplate拉伸的高度与分组项的高度相匹配?
无论我将VerticalAlignment / VerticalContentAlignment设置为什么,组标题都显示在组中第一个项目的左侧。
答案 0 :(得分:0)
无论我将VerticalAlignment / VerticalContentAlignment设置为什么,组标题都显示在组中第一个项目的左侧。
组头实际上是ListViewHeaderItem
个对象。通过查看ViewTree
,我们不会看到每个组的父容器(一个组包含一个ListViewHeaderItem
和几个ListViewItem
。)。因此,ListViewHeaderItem
似乎没有父控制来简化力量。但我们可以通过精确计算将ListViewHeaderItem
的高度设置为进行组项目。
在这里,我们可以使用ViewTreeHelper类首先获取AcualHeight
ListViewItem
,然后从绑定到XAML的组资源中获取当前组的项目数,现在可以计算组头高度。代码如下:
XAML代码
<Page.Resources>
<CollectionViewSource x:Name="cvsActivities" IsSourceGrouped="True" />
<CollectionViewSource
x:Name="cvsProjects"
IsSourceGrouped="True"
ItemsPath="Activities" />
<local:ListGroupStyleSelector x:Key="listGroupStyleSelector" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Padding="30">
<ListView
x:Name="CListView"
GroupStyleSelector="{StaticResource listGroupStyleSelector}"
ItemContainerStyle="{StaticResource ListViewItemExpanded}"
ItemTemplate="{StaticResource listViewItemTemplate}"
ItemsSource="{Binding Source={StaticResource cvsActivities}}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel GroupHeaderPlacement="Left" Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
背后的代码
public sealed partial class MainPage : Page
{
DateTime startDate;
IOrderedEnumerable<IGrouping<string, Activity>> result;
public MainPage()
{
this.InitializeComponent();
}
//Calculate the group height.
public void calculate()
{
IEnumerable<ListViewHeaderItem> headeritems = FindVisualChildren<ListViewHeaderItem>(CListView);
IEnumerable<ListViewItem> listviewitems = FindVisualChildren<ListViewItem>(CListView);
var listviewitemheight = listviewitems.FirstOrDefault().ActualHeight;
for (int i = 0; i < headeritems.Count(); i++)
{
ListViewHeaderItem headeritem = headeritems.ElementAt<ListViewHeaderItem>(i);
var currentgroup = result.ElementAt<IGrouping<string, Activity>>(i);
var groupcount = currentgroup.Count();
headeritem.Height = listviewitemheight * groupcount;
System.Diagnostics.Debug.WriteLine(headeritem.ActualHeight);
}
}
private static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
DateTime.TryParse("1/1/2014", out startDate);
PopulateActivities();
}
private void PopulateActivities()
{
List<Activity> Activities = new List<Activity>();
Activities.Add(new Activity()
{
Name = "Activity 1",
Complete = true,
DueDate = startDate.AddDays(4),
Project = "Project 1"
});
...
Activities.Add(new Activity()
{
Name = "Activity A",
Complete = true,
DueDate = startDate.AddDays(2),
Project = "Project 2"
});
...
result = from act in Activities group act by act.Project into grp orderby grp.Key select grp;
cvsActivities.Source = result;
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
calculate();
}
}
public class ListGroupStyleSelector : GroupStyleSelector
{
protected override GroupStyle SelectGroupStyleCore(object group, uint level)
{
return (GroupStyle)App.Current.Resources["listViewGroupStyle"];
}
}
public class Activity
{
public string Name { get; set; }
public DateTime DueDate { get; set; }
public bool Complete { get; set; }
public string Project { get; set; }
}
更新组样式的HeaderContainerStyle以使布局看起来整洁。
<GroupStyle x:Key="listViewGroupStyle">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock
VerticalAlignment="Center"
Foreground="Black"
Text="{Binding Key}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.HeaderContainerStyle>
<Style TargetType="ListViewHeaderItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ListViewHeaderItemThemeFontSize}" />
<Setter Property="Background" Value="Azure" />
<Setter Property="Margin" Value="0,0,0,0" />
<Setter Property="Padding" Value="0,0,0,0" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="MinHeight" Value="{ThemeResource ListViewHeaderItemMinHeight}" />
<Setter Property="UseSystemFocusVisuals" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewHeaderItem">
<Grid
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter
x:Name="ContentPresenter"
Margin="0"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="Stretch"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
<Rectangle
Height="1"
Margin="0,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Stroke="{ThemeResource SystemControlForegroundBaseLowBrush}"
StrokeThickness="0.5" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.HeaderContainerStyle>
</GroupStyle>
结果。