首页 > 解决方案 > 显示来自 api 调用 TextBlock (MVVM) 的单个值

问题描述

我已经坚持了几个小时了。我正在为我正在构建的应用程序使用 IGDB api。因此,我正在尝试获取必须显示游戏标题、封面和开发人员的 ListBox。我已经设法让他们所有人都毫无问题地出现在列表中,但是当我只想在列表中显示一个开发人员时,主要问题就出现了,列表显示了所有涉及的公司以及开发人员,因为 API返回一系列涉及的公司,在这些涉及的公司中,开发人员主体返回一个布尔值来说明哪个是开发人员。我可以在我的脑海中看到它,如果开发人员是真的,那么显示开发人员并删除其他相关公司。这是我运行查询时显示的图像:

查询图片

我已经用红色勾勒出来了。从该列表中,我只需要 Bungie,因为他们是开发人员。所以在我看来,我有一个 ListBox 和一个嵌套在其中的 ListView:

浏览游戏查看

<ListBox ItemsSource="{Binding Games}"
             Width="390"
             Height="500"
             Grid.Row="4">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Border Grid.Column="0"
                            Grid.Row="0"
                            Grid.RowSpan="2"
                            Margin="0 0 10 0">
                        <Image Source="{Binding cover.image_id, Converter={StaticResource stringToImage}}"
                               Stretch="Fill"
                               Height="70"
                               Width="60"/>
                    </Border>
                    <TextBlock Text="{Binding name}"
                               FontWeight="Bold"
                               Grid.Column="1"
                               Grid.Row="0"/>
                    <ListView Grid.Column="1"
                              Grid.Row="1"
                              ItemsSource="{Binding involved_companies}">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding company.name}"/>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

在我的 ViewModel 中,我有一种进行查询的方法,并且还保存了 ObservableCollection(游戏)。

浏览游戏查看模型

public ObservableCollection<Game> Games { get; set; }

public async void MakeQuery()
        {
            var games = await IGDBHelper.GetGames(Query);

            Games.Clear();
            foreach(var game in games)
            {
                Games.Add(game);
            }
        }

在我的助手类中,我得到了游戏

IGDB 助手

public static async Task<List<Game>> GetGames(string query)
        {
            List<Game> games = new List<Game>();

            string myJson = "search \"{0}\"; fields name, cover.url, cover.image_id, involved_companies.developer, involved_companies.company.name; limit 500;";

            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("user-key", "key hidden");

                var response = await client.PostAsync(BASE_URL_GAMES, new StringContent(string.Format(myJson, query), Encoding.UTF8, "application/json"));

                var responseString = await response.Content.ReadAsStringAsync();

                games = JsonConvert.DeserializeObject<List<Game>>(responseString);
            }

            return games;
        }

所有模型都是 Json 的具体类

public class Game
    {
        public int id { get; set; }
        public Cover cover { get; set; }
        public List<InvolvedCompany> involved_companies { get; set; }
        public string name { get; set; }
    }


public class InvolvedCompany
    {
        public int id { get; set; }
        public Company company { get; set; }
        public bool developer { get; set; }
    }

public class Company
    {
        public int id { get; set; }
        public string name { get; set; }
    }

public class Cover
{
    public int id { get; set; }
    public string image_id { get; set; }
    public string url { get; set; }
}

因此,重申一下,我需要通过从列表中删除其余相关公司来以某种方式显示开发人员的名称。我已经尝试了几件事,从转换器到在转换器类中尝试它,每次我得到 null 异常。

标签: c#wpfmvvm

解决方案


首先,我建议用 PascalCase 命名您的属性。现在对于您的问题,我建议按开发商财产过滤公司,并在将其添加到列表之前将涉及公司的新列表分配给游戏。

foreach(var game in games)
  {
     game.involved_companies = game.involved_companies.Where(e => e.developer == true).Tolist();
     Games.Add(game);
  }

未经测试,但我相信这应该有效。


推荐阅读