Maui 列表视图分组

huangapple go评论71阅读模式
英文:

Maui Listview grouping

问题

我有一个包含约100个对象的列表。每个对象有2个属性(名称,打卡时间)。类如下:

public class Trxs
{
    public string punch_time { get; set; }
    public string name { get; set;}
}

列表的名称是(Punch_Times):

List<Trxs> Punch_times = new List<Trxs>();

这是一个指纹机交易记录。我想要在Maui中填充一个列表视图,以便数据基于名称进行分组,如下:

应该显示如此

我尝试了以下对列表进行分组,它显示了分组后的列表,但没有显示分组名称。列表视图的名称是(Trx_List):

var sorted = Punch_times.GroupBy(x => x.name)
    .Select(grp => grp.ToList())
    .ToList();
        
Trx_List.ItemsSource = sorted ;

结果显示如下(分组名称为空):

但它显示为这样

我创建了一个表示新列表的类,它将是Trx_List的数据源,如下:

public class Grouped_list
{
    public string emp_name { get; set; }
    public List<Trxs> trxes { get; set; }
}

并创建了一个新列表:

List<Grouped_list> new_list = new List<Grouped_list>();

但是如何将项目从(sorted)复制到(new_list)。还是需要吗?如何使列表视图的数据源按名称分组?

请帮忙!

谢谢

英文:

I have a list which consists of around 100 object. Each object has 2 properties (name, punch_time). The class is as follows:

public class Trxs
{
    public string punch_time { get; set; }
    public string name { get; set;}
}

the list name is (Punch_Times):

List&lt;Trxs&gt; Punch_times = new List&lt;Trxs&gt;();

It is a finger-print machine transactions. I want to populate a list view in Maui, so that the data will be grouped based on the name, as below:
It should show like this

I Tried the following grouping of the list, It showed the list grouped but without the group name. The listview name is (Trx_List):

var sorted = Punch_times.GroupBy(x =&gt; x.name)
    .Select(grp =&gt; grp.ToList())
    .ToList();
        
Trx_List.ItemsSource = sorted ;

the result showed like this (the group names are empty):

But it is showing like this

I have created a class to represent to new list, which will be the item source of the Trx_List as follows:

public class Grouped_list
{
    public string emp_name { get; set; }
    public List&lt;Trxs&gt; trxes { get; set; }
}

And created a new list:

List&lt;Grouped_list&gt; new_list = new List&lt;Grouped_list&gt;();

but how to copy the items from (sorted) to (new_list). Or is it needed? how to make item source of the list view grouped by name?

Any help please!

Thank you

答案1

得分: 1

坦白说,我建议使用CollectionView而不是ListView。关于iOS的GroupHeaderTemplate存在已知问题:ListView GroupHeaderTemplate在iOS和MacCatalyst上生成空白标头。它只会渲染空白标头。这就是为什么我建议使用CollectionView。用法几乎相同。你可以参考在CollectionView中显示分组数据

对于你的情况,如何将sorted反映到new_list非常重要。我根据你的代码制作了一个小的演示,遵循了官方文档。

对于MainPageViewModel.cs

public class MainPageViewModel
{
    public List<Trxs> Punch_times { get; set; } = new List<Trxs>();
    public List<Grouped_list> new_list { get; set; } = new List<Grouped_list>();
    public MainPageViewModel()
    {
        //添加一些测试数据
        Punch_times.Add(new Trxs
        {
            name = "John",
            punch_time = "13:33"
        });
       //......
       //将列表转换为字典(键是name)
        var dict = Punch_times.GroupBy(o => o.name)
                   .ToDictionary(g => g.Key, g => g.ToList());

        foreach (KeyValuePair<string, List<Trxs>> item in dict)
        {
            new_list.Add(new Grouped_list(item.Key,new List<Trxs>(item.Value)));
        }
    }
}

对于Grouped_list.cs

public class Grouped_list : List<Trxs>
{
    public string Name { get; set; }

    public Grouped_list(string name, List<Trxs> trxs) : base(trxs)
    {
        Name = name;
    }
}

对于MainPage.xaml,它使用ListViewCollectionView

<CollectionView ItemsSource="{Binding new_list}" 
      IsGrouped="True">
    <CollectionView.GroupHeaderTemplate>
        <DataTemplate>
            <StackLayout>
                <Label Text="{Binding Name}" TextColor="Black" VerticalOptions="CenterAndExpand"
                       BackgroundColor="LightGray"
                       FontSize="20"
                       FontAttributes="Bold" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.GroupHeaderTemplate>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <StackLayout>
                <Label Text="{Binding punch_time}" BackgroundColor="Yellow"
                       FontSize="20" HorizontalTextAlignment="Center"
                       VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"/>
            </StackLayout>                 
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

或者你可以使用ListView,但在iOS上可能无法正确渲染,正如我上面提到的。

<ListView ItemsSource="{Binding new_list}" 
      IsGroupingEnabled="True">
    <ListView.GroupHeaderTemplate>
        <DataTemplate>
            <ViewCell>
                <Label Text="{Binding Name}" TextColor="Black" VerticalOptions="CenterAndExpand"
                       BackgroundColor="LightGray"
                       FontSize="20"
                       FontAttributes="Bold" />
            </ViewCell>
        </DataTemplate>
    </ListView.GroupHeaderTemplate>
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout>
                    <Label Text="{Binding punch_time}" BackgroundColor="Yellow"
                           FontSize="20" HorizontalTextAlignment="Center"
                           VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"/>
                </StackLayout>                 
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

更多信息,请参考ListView:显示分组数据在CollectionView中显示分组数据

希望对你有所帮助。

英文:

To be frank, I recommend to use CollectionView instead of ListView. There is a known issue about iOS GroupHeaderTemplate :ListView GroupHeaderTemplate produces blank headers on iOS and MacCatalyst. It just render a blank headers. That's why i recommend to use CollectionView. The usage is almost the same. You could refer to Display grouped data in a CollectionView.

For your case, how to reflect sorted to new_list really matters. I made a small demo following the official documentation based on your code.

For MainPageViewModel.cs,

public class MainPageViewModel
{
    public List&lt;Trxs&gt; Punch_times { get; set; } = new List&lt;Trxs&gt;();
    public List&lt;Grouped_list&gt; new_list { get; set; } = new List&lt;Grouped_list&gt;();
    public MainPageViewModel()
    {
        //Add some data for test
        Punch_times.Add(new Trxs
        {
            name = &quot;John&quot;,
            punch_time = &quot;13:33&quot;
        });
       ......
       // translate list to dict (key is name)
        var dict = Punch_times.GroupBy(o =&gt; o.name)
                   .ToDictionary(g =&gt; g.Key, g =&gt; g.ToList());

        foreach (KeyValuePair&lt;string, List&lt;Trxs&gt;&gt; item in dict)
        {
            new_list.Add(new Grouped_list(item.Key,new List&lt;Trxs&gt;(item.Value)));
        }
    }
}

For Grouped_list.cs,

public class Grouped_list : List&lt;Trxs&gt;
{
    public string Name { get; set; }


    public Grouped_list(string name, List&lt;Trxs&gt; trxs) : base(trxs)
    {
        Name = name;
    }
}

For MainPage.xaml which consumes the ListView or CollectionView,

&lt;CollectionView ItemsSource=&quot;{Binding new_list}&quot; 
      IsGrouped=&quot;True&quot;&gt;
        &lt;CollectionView.GroupHeaderTemplate&gt;
            &lt;DataTemplate&gt;
                &lt;StackLayout&gt;
                    &lt;Label Text=&quot;{Binding Name}&quot; TextColor=&quot;Black&quot; VerticalOptions=&quot;CenterAndExpand&quot;

                           BackgroundColor=&quot;LightGray&quot;
                           FontSize=&quot;20&quot;
                           FontAttributes=&quot;Bold&quot; /&gt;
                &lt;/StackLayout&gt;
            &lt;/DataTemplate&gt;
        &lt;/CollectionView.GroupHeaderTemplate&gt;
    &lt;CollectionView.ItemTemplate&gt;
        &lt;DataTemplate&gt;
                &lt;StackLayout&gt;
                    &lt;Label Text=&quot;{Binding punch_time}&quot; BackgroundColor=&quot;Yellow&quot;
                           FontSize=&quot;20&quot; HorizontalTextAlignment=&quot;Center&quot;
                           VerticalOptions=&quot;CenterAndExpand&quot; HorizontalOptions=&quot;CenterAndExpand&quot;/&gt;                                               
                &lt;/StackLayout&gt;                 
        &lt;/DataTemplate&gt;
    &lt;/CollectionView.ItemTemplate&gt;
&lt;/CollectionView&gt;

or you may use ListView but not render correctly on iOS as i mention above.

&lt;ListView ItemsSource=&quot;{Binding new_list}&quot; 
      IsGroupingEnabled=&quot;True&quot;&gt;
        &lt;ListView.GroupHeaderTemplate&gt;
            &lt;DataTemplate&gt;
                &lt;ViewCell&gt;
                    &lt;Label Text=&quot;{Binding Name}&quot; TextColor=&quot;Black&quot; VerticalOptions=&quot;CenterAndExpand&quot;

                           BackgroundColor=&quot;LightGray&quot;
                           FontSize=&quot;20&quot;
                           FontAttributes=&quot;Bold&quot; /&gt;
                &lt;/ViewCell&gt;
            &lt;/DataTemplate&gt;
        &lt;/ListView.GroupHeaderTemplate&gt;
    &lt;ListView.ItemTemplate&gt;
        &lt;DataTemplate&gt;
            &lt;ViewCell&gt;
                &lt;StackLayout&gt;
                    &lt;Label Text=&quot;{Binding punch_time}&quot; BackgroundColor=&quot;Yellow&quot;
                           FontSize=&quot;20&quot; HorizontalTextAlignment=&quot;Center&quot;
                           VerticalOptions=&quot;CenterAndExpand&quot; HorizontalOptions=&quot;CenterAndExpand&quot;/&gt;                                               
                &lt;/StackLayout&gt;                 
            &lt;/ViewCell&gt;
        &lt;/DataTemplate&gt;
    &lt;/ListView.ItemTemplate&gt;
&lt;/ListView&gt;

For more info, you could refer to ListView : Display grouped data and Display grouped data in a CollectionView

Hope it works for you.

答案2

得分: 0

public class Grouped_list : List<Trxs>
{
    public string emp_name { get; set; }

    public Grouped_list(string name, List<Trxs> list) : base(list)
    {
        emp_name = name;
    }
}

你需要类似这样的结构。

然后你的可观察对象是:

public ObservableCollection<Grouped_list> GroupedLists...

将其设置为ItemSource,并且不要忘记将IsGrouped设置为true

GroupHeaderTemplate中应该绑定到emp_name
DataType应为Grouped_list

另外,应该是EmpName,而不是emp_name
遵循命名规范。
英文:
public class Grouped_list : List&lt;Trxs&gt;
{
    public string emp_name { get; set; }

    public Grouped_list(string name, List&lt;Trxs&gt; list) : base(list)
    {
        emp_name = name;
    }
}

You need something like that.

And then your observable is:

public ObservableCollection&lt;Grouped_list&gt; GroupedLists...

Set it as ItemSource, and don't forget to set IsGrouped to true.

In the GroupHeaderTemplate there should be binding to emp_name.
And its DataType should be Grouped_list.

Also, It is EmpName, not emp_name. And GroupedList not Grouped_list.
Follow the naming conventions.

huangapple
  • 本文由 发表于 2023年2月14日 03:02:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75440184.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定