Win 10 UAP ListView 条件分隔符
Win 10 UAP ListView Conditional Separator
对于 ListView,我想在项目之间显示一个分隔符。然而,有点困难的是它只应在日期更改时显示。
所以我想要列出 1.1.2015 的所有项目。在 2.1.2015 的项目开始之前,应该有一个分隔符(在这种情况下只是带有日期的文本)。
因此我需要以某种方式访问最后一项。
我的想法是在 <LV.ItemTemplate><DataTemplate>
的开头放置一个文本框,绑定日期并将其可见性挂接到转换器。但是为此,转换器需要知道之前的日期。
这可以非常简单地使用开箱即用的 ListView
和绑定 ListView
的分组 CollectionViewSource
来完成。
关于如何执行此操作的非常简单的概述:
在您的 xaml 页面中,添加
<Page.Resources>
<CollectionViewSource x:Name="itemsViewSource" IsSourceGrouped="true" />
</Page.Resources>
对于 ListView 你可以这样做
<ListView x:Name="friendsList" Width="200" Grid.Column="0" ItemsSource="{Binding Source={StaticResource itemsViewSource}}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock
Text="{Binding Key}"
FontSize="40" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Margin="8" Width="32" Height="32">
<Ellipse.Fill>
<ImageBrush x:Name="UserHero" Stretch="Uniform" ImageSource="{Binding picture.small}"/>
</Ellipse.Fill>
</Ellipse>
<TextBlock Text="{Binding first_name}" Margin="8" VerticalAlignment="Center"/>
<TextBlock Text="{Binding last_name}" Margin="8" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
此代码段将 ListView
的 itemsSource 绑定到上面定义的 itemsViewSource
CollectionViewSource
。 DataTemplate
恰好包含您想要的:要在元素组之间显示的分隔线!这可以绑定到分组数据所属的键和一个转换器用来做任何你想做的事情!
然后从与源数据中的键配对的列表对象中显示 ListView
项。
现在这行得通了,我们如何将数据转换成我们 xaml 想要的格式以使用此...
在后面的代码中,我假设您有 List
个要显示的对象,因为我没有从您的原始问题中获得任何信息,例如 private List<Object> _objects
.我们需要做的是将其转换为 List<GroupedInfoList<Object>> _groupedObjects
.
我们可以使用美妙的 LINQ
来做到这一点。为了说明这一点,我将向您展示我的一个项目中使用真实数据对象的片段(对象的详细信息并不重要):
public async Task<List<GroupInfoList<object>>> GetFriendsGrouped()
{
if(_friends == null)
{
_friends = await NetworkManager.GetFriends();
}
List<GroupInfoList<object>> friendsGrouped = new List<GroupInfoList<object>>();
var query = from friend in _friends
orderby ((Friend)friend).first_name
group friend by ((Friend)friend).first_name[0] into g
select new { GroupName = g.Key, Items = g };
foreach (var g in query)
{
GroupInfoList<object> info = new GroupInfoList<object>();
info.Key = g.GroupName;
foreach (var friend in g.Items)
{
info.Add(friend);
}
friendsGrouped.Add(info);
}
return friendsGrouped;
}
此代码段获取 Friend
个对象的列表,并按它们的 string first_name
属性对它们进行分组。您显然需要调整此 LINQ 查询以按您想要的日期对对象进行分组!
有了分组对象后,您需要将其绑定到代码前端中的 ListView
:
if (_friendsGrouped != null)
{
var cvs = (CollectionViewSource)Resources["itemsViewSource"];
cvs.Source = _friendsGrouped;
}
希望对您有所帮助!
编辑:
如 OP 所述,GroupInfoList
不作为标准存在 class,我自己定义如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace App.Models
{
public class GroupInfoList<T> : List<object>
{
public object Key { get; set; }
public new IEnumerator<object> GetEnumerator()
{
return (System.Collections.Generic.IEnumerator<object>)base.GetEnumerator();
}
}
}
对于 ListView,我想在项目之间显示一个分隔符。然而,有点困难的是它只应在日期更改时显示。
所以我想要列出 1.1.2015 的所有项目。在 2.1.2015 的项目开始之前,应该有一个分隔符(在这种情况下只是带有日期的文本)。 因此我需要以某种方式访问最后一项。
我的想法是在 <LV.ItemTemplate><DataTemplate>
的开头放置一个文本框,绑定日期并将其可见性挂接到转换器。但是为此,转换器需要知道之前的日期。
这可以非常简单地使用开箱即用的 ListView
和绑定 ListView
的分组 CollectionViewSource
来完成。
关于如何执行此操作的非常简单的概述:
在您的 xaml 页面中,添加
<Page.Resources>
<CollectionViewSource x:Name="itemsViewSource" IsSourceGrouped="true" />
</Page.Resources>
对于 ListView 你可以这样做
<ListView x:Name="friendsList" Width="200" Grid.Column="0" ItemsSource="{Binding Source={StaticResource itemsViewSource}}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock
Text="{Binding Key}"
FontSize="40" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Margin="8" Width="32" Height="32">
<Ellipse.Fill>
<ImageBrush x:Name="UserHero" Stretch="Uniform" ImageSource="{Binding picture.small}"/>
</Ellipse.Fill>
</Ellipse>
<TextBlock Text="{Binding first_name}" Margin="8" VerticalAlignment="Center"/>
<TextBlock Text="{Binding last_name}" Margin="8" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
此代码段将 ListView
的 itemsSource 绑定到上面定义的 itemsViewSource
CollectionViewSource
。 DataTemplate
恰好包含您想要的:要在元素组之间显示的分隔线!这可以绑定到分组数据所属的键和一个转换器用来做任何你想做的事情!
然后从与源数据中的键配对的列表对象中显示 ListView
项。
现在这行得通了,我们如何将数据转换成我们 xaml 想要的格式以使用此...
在后面的代码中,我假设您有 List
个要显示的对象,因为我没有从您的原始问题中获得任何信息,例如 private List<Object> _objects
.我们需要做的是将其转换为 List<GroupedInfoList<Object>> _groupedObjects
.
我们可以使用美妙的 LINQ
来做到这一点。为了说明这一点,我将向您展示我的一个项目中使用真实数据对象的片段(对象的详细信息并不重要):
public async Task<List<GroupInfoList<object>>> GetFriendsGrouped()
{
if(_friends == null)
{
_friends = await NetworkManager.GetFriends();
}
List<GroupInfoList<object>> friendsGrouped = new List<GroupInfoList<object>>();
var query = from friend in _friends
orderby ((Friend)friend).first_name
group friend by ((Friend)friend).first_name[0] into g
select new { GroupName = g.Key, Items = g };
foreach (var g in query)
{
GroupInfoList<object> info = new GroupInfoList<object>();
info.Key = g.GroupName;
foreach (var friend in g.Items)
{
info.Add(friend);
}
friendsGrouped.Add(info);
}
return friendsGrouped;
}
此代码段获取 Friend
个对象的列表,并按它们的 string first_name
属性对它们进行分组。您显然需要调整此 LINQ 查询以按您想要的日期对对象进行分组!
有了分组对象后,您需要将其绑定到代码前端中的 ListView
:
if (_friendsGrouped != null)
{
var cvs = (CollectionViewSource)Resources["itemsViewSource"];
cvs.Source = _friendsGrouped;
}
希望对您有所帮助!
编辑:
如 OP 所述,GroupInfoList
不作为标准存在 class,我自己定义如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace App.Models
{
public class GroupInfoList<T> : List<object>
{
public object Key { get; set; }
public new IEnumerator<object> GetEnumerator()
{
return (System.Collections.Generic.IEnumerator<object>)base.GetEnumerator();
}
}
}