Search code examples
c#listviewuwponitemclick

Get ListView item's details on ItemClick() event


I've tried searching around here and on microsoft docs but I can't find a solution to my specific query, as mainly I've seen posts about how to do things on itemclick rather than retrieve data.

I'm currently using an API, which sends a JSON request that I deserialize into 2 partial classes, where I use a foreach loop to add new items to the ListView. You can see the classes here:

public partial class GameListObject
    {
        [JsonPropertyName("id")]
        public long GameID { get; set; }

        [JsonPropertyName("name")]
        public string GameName { get; set; }

        [JsonPropertyName("release_dates")]
        public ObservableCollection<ReleaseDate> ReleaseDates { get; set; }
    }

    public partial class ReleaseDate
    {
        [JsonPropertyName("id")]
        public long Id { get; set; }

        [JsonPropertyName("human")]
        public string Human { get; set; }
    }

And the request, deserialization and adding to the ListView here:

//On search box content change
    private async void gamehub_search_TextChanged(object sender, TextChangedEventArgs e)
    {
        var SearchQuery = gamehub_search.Text;

        try
        {
            // Construct the HttpClient and Uri
            HttpClient httpClient = new HttpClient();
            Uri uri = new Uri("https://api.igdb.com/v4/games");

            httpClient.DefaultRequestHeaders.Add("Client-ID", App.GlobalClientidIGDB);
            httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + App.GlobalAccessIGDB);
            //Debug.WriteLine("Request Headers: ");

            // Construct the JSON to post
            HttpStringContent content = new HttpStringContent($"search \"{SearchQuery}\"; fields name,release_dates.human;");
            Debug.WriteLine("Request Contents: " + content);

            // Post the JSON and wait for a response
            HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(
                uri,
                content);

            // Make sure the post succeeded, and write out the response
            httpResponseMessage.EnsureSuccessStatusCode();
            var httpResponseBody = await httpResponseMessage.Content.ReadAsStringAsync();
            Debug.WriteLine("Request Response: " + httpResponseBody);

            //Deserialise the return output into game id, game name and release date
            List<GameListObject> gamelistobjects = JsonSerializer.Deserialize<List<GameListObject>>(httpResponseBody);

            ObservableCollection<GameListObject> dataList = new ObservableCollection<GameListObject>(gamelistobjects);
            ObservableCollection<GameListObject> GameList = new ObservableCollection<GameListObject>();

            foreach (var item in dataList)
            {
                Debug.WriteLine($"id: {item.GameID}");
                Debug.WriteLine($"name: {item.GameName}");

                GameListObject add = new GameListObject() { GameID = item.GameID, GameName = item.GameName };
                GameList.Add(add);

                if (item.ReleaseDates != null)
                {
                    foreach (var date in item.ReleaseDates)
                    {
                        Debug.WriteLine($"releaseDate: {date.Human}");
                    }
                }
            }
            gamehub_list.ItemsSource = GameList;
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
    }

Now I have set an gamehub_list_ItemClick method which runs when an item within the ListView is pressed. I would like to retrieve the GameID that's present in that item because I'll need that for another page which the user gets redirected to so that I know what game I must request data for. However, I've tried finding the index of the item and using the member names of the class to retrieve it but I can't seem to get it working.

The ItemClick method currently is:

private void gamehub_list_ItemClick(object sender, ItemClickEventArgs e) //When an item in List View is pressed
    {
        string clickedItemText = e.ClickedItem.ToString();

        Debug.WriteLine("Click Item text: " + clickedItemText);
    }

When I tried to get the index of the item, it always returned as -1 and for the current clickedItemText it returns "Click Item text: ReviewR.GameHubs+GameListObject".

My xaml with the ListView:

<ListView x:Name="gamehub_list" SelectionMode="None" IsItemClickEnabled="True" ItemClick="gamehub_list_ItemClick" Margin="30,140,44,30" BorderThickness="5" BorderBrush="Black" Background="Gray" RequestedTheme="Dark" Visibility="Collapsed">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <StackPanel>
                                <TextBlock Text="{Binding GameID}"></TextBlock>
                                <TextBlock Text="{Binding GameName}"></TextBlock>
                            </StackPanel>
                        </Grid>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

Solution

  • Click Item text: ReviewR.GameHubs+GameListObject

    The problem is ClickedItem is object type, if you pass it to string directly, it will return text like you mentioned above.

    For this scenario, you need unbox ClickedItem.

    var clickedItem = e.ClickedItem as GameListObject
    Debug.WriteLine("Click Item text: " + clickedItem.GameID );