使用.net maui,从列表创建CollectionView时,如何访问另一个列表以根据ID提取详细信息?

问题描述 投票:0回答:1

我对 xaml 和 .net maui 还很陌生,但我真的不知道该使用哪些搜索词。我想用集合视图在 xaml 中列出今天的任务通知。我希望此列表在 xaml 集合视图中显示时,使用 TaskID 作为标识符键从另一个列表中提取详细信息。

例如,大致:

    class Notification:
       int Id;
       int TaskID;
       int Title;
       DateTime NotificationTime;

    class Task:
       int Id;
       string Name;
       string Details;
    UpcomingNotificationsViewModel:
    
    List<Notification> NotificationsList { get; set; }
    List<Task> TasksList { get; set; }

    async void LoadData()
    {
        var result = from s in NotificationsList
              where s.NotificationTime.Date == today
              group s by s.NotificationTime into g
              select new GroupedNotification{ NotificationTime = g.Key, Notification = g.ToList() };

        GroupedNotifications = result;
    }


    public class GroupedNotification
    {
        public DateTime NotifyTime { get; set; }
        public List<Notification> Notification { get; set; }
    }

在 XAML 中,在迭代通知的 CollectionView 时,我还想从 TasksList 中提取数据,例如 Task.Name、Task.Details 等。

    <CollectionView ItemsSource="{Binding GroupedNotifications}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <VerticalStackLayout>
                <!-- Display the group header (time) -->
                <Label Text="{Binding NotifyTime, StringFormat='{}{0:h\\:mm tt}'}"
        FontAttributes="Bold"
        TextColor="Blue"/>

            <!-- Display the notifications within the group -->
            <CollectionView ItemsSource="{Binding Notification}">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                            <Grid Padding="0,5">
                                <Frame Padding="10,10">
                                    <StackLayout>
                                        <Label Text="{Binding Title}" />
                                        <Label Text="{Binding NotificationTime}" />
//this label below, how can I link it to TaskList and get details based on TaskID from this Notification List?
                                        <Label Text="{Binding How can I link this to show Task details based on the ID??}"   />
                                        <!-- Other properties... -->
                                    </StackLayout>
                                </Frame>
                            </Grid>
                        </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
            </VerticalStackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
    </CollectionView>`

我尝试了这段代码的几个不同的迭代,我尝试搜索过去三个小时,尝试询问 ChatGPT 和 Gemini,但我找不到我要找的东西。我需要有人为我指明正确的方向。

c# .net xaml maui collectionview
1个回答
0
投票

您可以尝试在卡片模型中嵌套

ObservableCollection
。如何检索“今天的任务通知列表”是次要的(您可以查询数据库或其他方式)。但这里的关键是,当您将这些项目添加到卡片的
SubItems
集合中时,UI 将正确绑定并做出响应。

这就是我的意思:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local ="clr-namespace:VariableSubitemsPOC"
             x:Class="VariableSubitemsPOC.MainPage">
    <ContentPage.BindingContext>
        <local:MainPageBindingContext />
    </ContentPage.BindingContext>
    <Grid
        Padding="30,0" 
        RowDefinitions="70, *">
        <Image
            Source="dotnet_bot.png"
            HeightRequest="70"
            Aspect="AspectFit"
            VerticalOptions="Center"
            SemanticProperties.Description="dot net bot in a race car number eight" />
        <CollectionView 
            Grid.Row="1"
            ItemsSource="{Binding Items}" 
            BackgroundColor="Azure">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Frame
                        Padding="10"
                        Margin="5"
                        BorderColor="Gray"
                        CornerRadius="10"
                        HasShadow="True">
                        <StackLayout>
                            <Label Text="{Binding Description}" 
                               FontAttributes="Bold"
                               FontSize="Medium"
                               HorizontalOptions="Center" />
                            <StackLayout>
                                <StackLayout BindableLayout.ItemsSource="{Binding SubItems}">
                                    <BindableLayout.ItemTemplate>
                                        <DataTemplate>
                                            <Label Text="{Binding Description}" FontSize="Small"/>
                                        </DataTemplate>
                                    </BindableLayout.ItemTemplate>
                                </StackLayout>
                            </StackLayout>
                        </StackLayout>
                    </Frame>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Grid>
</ContentPage>

卡牌类
class Card : INotifyPropertyChanged
{
    public string? Description
    {
        get => _description;
        set
        {
            if (!Equals(_description, value))
            {
                _description = value;
                OnPropertyChanged();
            }
        }
    }
    string? _description = default;

    public ObservableCollection<SubItem>? SubItems { get; set; } = new ObservableCollection<SubItem>();

    protected virtual void OnPropertyChanged([CallerMemberName]string? propertyName = null) => 
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    public event PropertyChangedEventHandler? PropertyChanged;
    public override string ToString() => Description ?? string.Empty;
}

子项目类
class SubItem : INotifyPropertyChanged
{
    public string? Description
    {
        get => _description;
        set
        {
            if (!Equals(_description, value))
            {
                _description = value;
                OnPropertyChanged();
            }
        }
    }
    string? _description = default;

    protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    public event PropertyChangedEventHandler? PropertyChanged;
    public override string ToString() => Description ?? string.Empty;
}

主页
public partial class MainPage : ContentPage
{
    public MainPage() => InitializeComponent();
}
class MainPageBindingContext
{
    public MainPageBindingContext()
    {
        for (int i = 3; i < 7; i++)
        {
            Items.Add(new Card
            {
                Description = DateTime.Now.AddDays(i).ToString("dddd"),
            });
        }
        _ = ExecAddDynamicSubitemsTest();
    }

    private async Task ExecAddDynamicSubitemsTest()
    {
        const int TEST_CARD_INDEX = 3;
        for (int i = 1; i <= 4; i++)
        {
            await Task.Delay(1000); 
            var newTaskDescription = $"Dynamic Task {i}";
            Items[TEST_CARD_INDEX].SubItems.Add(new SubItem { Description = newTaskDescription });
        }
    }

    public ObservableCollection<Card> Items { get; } = new ObservableCollection<Card>
    {
        new Card
        {
            Description = "Today",
            SubItems = new ObservableCollection<SubItem>
            {
                new SubItem { Description = "Plan the week" },
                new SubItem { Description = "Study Econ" },
                new SubItem { Description = "Meditate for 10 minutes" },
            }
        },
        new Card
        {
            Description = "Tomorrow",
            SubItems = new ObservableCollection<SubItem>
            {
                new SubItem { Description = "Go for a morning run" },
                new SubItem { Description = "Prepare breakfast" }
            }
        },
        new Card
        {
            Description = DateTime.Now.AddDays(2).ToString("dddd"),
            SubItems = new ObservableCollection<SubItem>
            {
                new SubItem { Description = "Call a friend" },
                new SubItem { Description = "Sort emails" },
                new SubItem { Description = "Plan the week ahead" },
                new SubItem { Description = "Walk Jeremy's dog" },
                new SubItem { Description = "Write in journal" },
            }
        }
    };
}
© www.soinside.com 2019 - 2024. All rights reserved.