如何迭代.NET MAUI页面XML中的字典观测

发布于 2025-02-05 05:07:03 字数 2993 浏览 0 评论 0 原文

我有一个来自JSON的数据结构:

{
"07-2022": [],
"08-2022": [
    {
        "event_title": "asdf"
        "positions": [
            {
                "position_title": "Graphics Op"
            },
            {
                "position_title": "Graphic Design"
            }
        ]
    }
],
"06-2023": []
}

我在代码中有用于工作和位置的模型,

public class OpenJob {
    // props...
    public List<Position> positions { get; set; }
}

我获取数据并将其放入字典中

Dictionary<string, List<Models.OpenJob>> OpenJobList = new();

public async Task<Dictionary<string, List<Models.OpenJob>>> getOpenJobs() {
        if (OpenJobList?.Count > 0) {
            return OpenJobList;
        }
        var url = "https://api.com";
        var response = await httpClient.GetAsync(url);

        if (response.IsSuccessStatusCode) {
            //Debug.WriteLine(response.ToString);
            OpenJobList = await response.Content.ReadFromJsonAsync<Dictionary<string, List<Models.OpenJob>>>();
        }
        return OpenJobList;
    }

,然后在我的ViewModel中将其转移到

//...
public ObservableCollection<Dictionary<string, List<OpenJob>>> OpenJobsCollection { get; } = new();
//...
try {
    IsBusy = true;
    var openJobs = await jobsService.getOpenJobs();
    
    if (OpenJobsCollection.Count > 0) {
        OpenJobsCollection.Clear();
    }
    OpenJobsCollection.Add(openJobs);
 }

XML页面中的观察力collection,我知道如何知道如何知道如何迭代一个简单的列表。但是我找不到有关此数据结构的解决方案。

VerticalStackLayout>
    <CollectionView
        ItemsSource="{This Should be the Dictionary}"
        SelectionMode="None">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="THIS SHOULD BE THE STRING KEY">
                <Frame>
                    <CollectionView
                          ItemSource="{This should be the List of OpenJob Models}" />
                          <CollectionView.ItemTemplate>
                              <DataTemplate x:DataType="Models.OpenJob">
                                  <Label Text="{Binding event_title}"/>
                              </DataTemplate>
                          </CollectionView.ItemTemplate>
                    </CollectionView>
                </Frame>
            </DataTemplate>
        </CollectionView.ItemTemplate>
        
     </CollectionView>
    
    <Button Text="Get Open Jobs"
            Command="{Binding GetOpenJobsCommand}"
            IsEnabled="{Binding IsNotBusy}"
            />
    <ActivityIndicator IsVisible="{Binding IsBusy}"
                       IsRunning="{Binding IsBusy}"
                       HorizontalOptions="FillAndExpand"
                       VerticalOptions="CenterAndExpand"
                       />
</VerticalStackLayout>

I have a data structure that comes from JSON:

{
"07-2022": [],
"08-2022": [
    {
        "event_title": "asdf"
        "positions": [
            {
                "position_title": "Graphics Op"
            },
            {
                "position_title": "Graphic Design"
            }
        ]
    }
],
"06-2023": []
}

I have models for the Job and Position

public class OpenJob {
    // props...
    public List<Position> positions { get; set; }
}

In my code I fetch the data and put it into a Dictionary

Dictionary<string, List<Models.OpenJob>> OpenJobList = new();

public async Task<Dictionary<string, List<Models.OpenJob>>> getOpenJobs() {
        if (OpenJobList?.Count > 0) {
            return OpenJobList;
        }
        var url = "https://api.com";
        var response = await httpClient.GetAsync(url);

        if (response.IsSuccessStatusCode) {
            //Debug.WriteLine(response.ToString);
            OpenJobList = await response.Content.ReadFromJsonAsync<Dictionary<string, List<Models.OpenJob>>>();
        }
        return OpenJobList;
    }

Then In my ViewModel I transfer it to an ObservableCollection

//...
public ObservableCollection<Dictionary<string, List<OpenJob>>> OpenJobsCollection { get; } = new();
//...
try {
    IsBusy = true;
    var openJobs = await jobsService.getOpenJobs();
    
    if (OpenJobsCollection.Count > 0) {
        OpenJobsCollection.Clear();
    }
    OpenJobsCollection.Add(openJobs);
 }

Finally in my xml page I know how to iterate a simple List. But I can't find a solution for this data structure.

VerticalStackLayout>
    <CollectionView
        ItemsSource="{This Should be the Dictionary}"
        SelectionMode="None">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="THIS SHOULD BE THE STRING KEY">
                <Frame>
                    <CollectionView
                          ItemSource="{This should be the List of OpenJob Models}" />
                          <CollectionView.ItemTemplate>
                              <DataTemplate x:DataType="Models.OpenJob">
                                  <Label Text="{Binding event_title}"/>
                              </DataTemplate>
                          </CollectionView.ItemTemplate>
                    </CollectionView>
                </Frame>
            </DataTemplate>
        </CollectionView.ItemTemplate>
        
     </CollectionView>
    
    <Button Text="Get Open Jobs"
            Command="{Binding GetOpenJobsCommand}"
            IsEnabled="{Binding IsNotBusy}"
            />
    <ActivityIndicator IsVisible="{Binding IsBusy}"
                       IsRunning="{Binding IsBusy}"
                       HorizontalOptions="FillAndExpand"
                       VerticalOptions="CenterAndExpand"
                       />
</VerticalStackLayout>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

野却迷人 2025-02-12 05:07:03

考虑一下您是否真的需要嵌套收集视图。通常有更好的解决方案,涉及不可滚动的布局。稍后我给你一个例子。

您在ViewModel中有三个嵌套集合( observableCollection dictionary list&lt; openjob&gt; ),所以要小心,因为您的第一个视图中的布局必须绑定 observableCollection ,而不是字典

我给您的另一个建议是使用自定义类而不是字典,因为这允许您继续使用 x:datatype ,而如果您继续使用字典,则要删除它,否则将生成编译时错误。

您可以以这种方式在XAML中迭代字典:

<!-- D is the dictionary in your viewmodel -->
<!-- In your case it will be bound from the ObservableCollection -->

<CollectionView
    ItemsSource="{Binding D}"
    >
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <VerticalStackLayout
                BindableLayout.ItemsSource="{Binding .}"
                >
                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <VerticalStackLayout>
                            <Label Text="{Binding Key}" />
                            <Label Text="{Binding Value}" />
                        </VerticalStackLayout>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </VerticalStackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

如果您确实需要嵌套CollectionViews,则只需用另一个 verticalStackLayout 用另一个 Collection> Collection> Collection> Collection view 替换 > bindableLayout 带有经典的标签。

Consider if you REALLY need to nest CollectionViews. There are often better solutions, involving not scrollable layouts. I'll give you an example of this later.

You have three nested collections in your viewmodel (the ObservableCollection, the Dictionary and the List<OpenJob>), so be careful, because your first layout in the view has to bind the ObservableCollection, not the Dictionary.

Another suggestion I would give you is to use a custom class instead of Dictionary, because that allows to you to keep using x:DataType, while if you keep using Dictionaries you have to remove it, otherwise a compile-time error will be generated.

You can iterate over a Dictionary in xaml in this way:

<!-- D is the dictionary in your viewmodel -->
<!-- In your case it will be bound from the ObservableCollection -->

<CollectionView
    ItemsSource="{Binding D}"
    >
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <VerticalStackLayout
                BindableLayout.ItemsSource="{Binding .}"
                >
                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <VerticalStackLayout>
                            <Label Text="{Binding Key}" />
                            <Label Text="{Binding Value}" />
                        </VerticalStackLayout>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </VerticalStackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

If you really need to nest CollectionViews, you simply have to replace the outer VerticalStackLayout with another CollectionView and replace the BindableLayout tags with the classic ones.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文