【问题标题】:How to use GroupHeader template of a ListView in Xamarin UWP using ListViewRenderer如何使用 ListViewRenderer 在 Xamarin UWP 中使用 ListView 的 GroupHeader 模板
【发布时间】:2017-02-06 03:33:24
【问题描述】:

我在App.xaml 中定义了以下HeaderTemplate

<DataTemplate x:Key="ListViewGroupHeaderTemplate">
    <TextBlock Foreground="Black" Text="Something" />
</DataTemplate>

我在我的ListViewRenderer 中使用这种方式:

listView.ItemTemplate = App.Current.Resources["ListViewItemTemplate"] as Windows.UI.Xaml.DataTemplate;
var gs = new GroupStyle();
gs.HeaderTemplate = App.Current.Resources["ListViewGroupHeaderTemplate"] as Windows.UI.Xaml.DataTemplate;
listView.GroupStyle.Add(gs);

ListView的来源是CollectionViewSource

CollectionViewSource cvs = new CollectionViewSource();
cvs.IsSourceGrouped = true;

cvs.Source = ((SourceListView)Element).Items;
if (listView.ItemsSource == null)
  listView.ItemsSource = cvs.View;

ItemTemplate 运行良好。

这就是我的ListView 的样子(白色部分是组标题):

我应该设置什么来使标题起作用?

更新

我根据答案修改了我的来源(应用分组到一个简单的列表):

    CollectionViewSource cvs = new CollectionViewSource();
    cvs.IsSourceGrouped = true;
    var items = ((MyListView)Element).Items;
    var itemsAsOC = items as ObservableCollection<GroupListItem>;
    List<ListItem> list = new List<ListItem>();
    foreach (var item in itemsAsOC)
    {
      list.AddRange(item);
    }
    var group = from item in list group item by item.Value into grp orderby grp.Key select grp;                
    cvs.Source = group;

标头没有任何变化,所以我猜数据源是正确的,但是模板处理中存在一些严重的 Xamarin UWP 错误:

更新 2:

我在没有 Xamarin 渲染器的情况下测试了它,它显示了标题项。

但是,当我使用 Xamarin 渲染器时,标题消失了

您可以download 并对其进行实际测试。

【问题讨论】:

    标签: uwp xamarin.uwp


    【解决方案1】:

    基本上我在您的代码中找不到任何明显的问题,这是我将GroupHeader 模板添加到ListView 的方法。

    在 App.xaml 中:

    <Application.Resources>
        <DataTemplate x:Key="ListViewGroupHeaderTemplate">
            <TextBlock Foreground="Red" Text="{Binding Key}" />
        </DataTemplate>
        <DataTemplate x:Key="ListViewTemplate">
            <TextBlock Foreground="Black" Text="{Binding DateTimeProperty}" />
        </DataTemplate>
    </Application.Resources>
    

    这是我的物品类别和我的SourceListView

    public class ListItem
    {
        public DateTime DateTimeProperty { get; set; }
    }
    
    public class SourceListView
    {
        public SourceListView()
        {
            Element = from x in Collection group x by x.DateTimeProperty.Year into grp orderby grp.Key select grp;
        }
    
        public IList<ListItem> Collection { get; set; } = new List<ListItem>()
        {
            new ListItem() {DateTimeProperty = DateTime.Parse("2011-08-01") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2011-08-21") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2012-04-03") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2012-04-01") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2013-05-15") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2013-05-06") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2013-05-01") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2013-06-01") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2013-06-09") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2014-10-02") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2014-10-11") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2015-12-03") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2016-07-01") },
            new ListItem() {DateTimeProperty = DateTime.Parse("2016-07-06") },
        };
    
        public IEnumerable<object> Element { get; }
    }
    

    这里是这个分组ListView的实现代码:

    ListView listView = new ListView();
    listView.ItemTemplate = App.Current.Resources["ListViewTemplate"] as Windows.UI.Xaml.DataTemplate;
    var gs = new GroupStyle();
    gs.HeaderTemplate = App.Current.Resources["ListViewGroupHeaderTemplate"] as Windows.UI.Xaml.DataTemplate;
    listView.GroupStyle.Add(gs);
    
    CollectionViewSource cvs = new CollectionViewSource();
    cvs.IsSourceGrouped = true;
    cvs.Source = new SourceListView().Element;
    if (listView.ItemsSource == null)
        listView.ItemsSource = cvs.View;
    rootGrid.Children.Add(listView);
    

    这是渲染图:

    【讨论】:

    • 如果我添加以下代码:˛listView.HeaderTemplate = App.Current.Resources["ListViewGroupHeaderTemplate"] as Windows.UI.Xaml.DataTemplate;,然后出现主标题,所以我猜,组标题设置错误。我应该在我的 CollectionViewSource 中设置键值吗?
    • @Nestor,如果你设置了listView.HeaderTemplate = App.Current.Resources["ListViewGroupHeaderTemplate"] as Windows.UI.Xaml.DataTemplate;,那么这个header就是这个ListView的主header,你的group应该是通过item in order来构建失败的,但是每个group的header应该是缺失的。 .."Should I set a key value in my CollectionViewSource", key value是分组标题,它使用LinQ进行分组,分组时它们是键值对,所以我在@中使用Key进行绑定987654333@,在CollectionViewSource,你只需要添加这个模板。
    • 我修改了我的模板,fix title 被替换为{Binding Key},但没有任何改变。另外,我想修复标题应该是可见的,因为它在绑定时不依赖任何东西。我将GroupStyle 添加到我的XAML,但标题仍然是一个白色矩形。很奇怪,妨碍了我的工作。
    • 我在最初的问题中添加了一些信息。我没有足够强调它是我使用的 Xamarin ListViewRenderer。
    【解决方案2】:

    好的,经过一天半的努力解决这个问题后,我终于找到了解决方案。如果有一天有人遇到和我一样的问题,我会在这里发布。其实这是一个很奇怪的问题,我不知道这是一个错误,未实现的功能还是什么......

    解决办法:

    在您的 UWP 自定义渲染器中,您需要这样做:

     protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
        {
            base.OnElementChanged(e);
    
            if (e.NewElement != null)
            {
                e.NewElement.GroupHeaderTemplate = new Xamarin.Forms.DataTemplate(() =>
                {
                    var label = new Label();
    
                    label.SetBinding(Label.TextProperty, "Country");
    
                    return new ViewCell { View = label };
                });
            }
        }
    

    其中“国家/地区”是代表您的组/标题的类中的属性名称。

    【讨论】:

      猜你喜欢
      • 2020-11-10
      • 2019-05-27
      • 2016-05-30
      • 2016-04-13
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 2017-08-15
      • 2017-07-30
      相关资源
      最近更新 更多