UWP - 使用GroupHeaderPlacement = Left的ItemsStackPanel中的HeaderTemplate的拉伸高度

时间:2016-12-02 18:19:24

标签: uwp uwp-xaml groupstyle

在ItemsControl或ListView中,是否可以使GroupStyle.HeaderTemplate拉伸的高度与分组项的高度相匹配?

无论我将VerticalAlignment / VerticalContentAlignment设置为什么,组标题都显示在组中第一个项目的左侧。

1 个答案:

答案 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>

结果。

enter image description here