C#: Getting ListView Tag

trevor1940
trevor1940 used Ask the Experts™
on
I think this is probably linked to previous question  

Using TMDB API I have a ListView on a Winform showing a list of people from a search

I'm adding each Person to the item tag but am unable to retrieve the properties of the tag on selection

Thinking I needed to cast it to an object I created  public class FoundPerson by Paste as JSON form developers.themoviedb API

        private void DoSearch()
        {
            TMDbClient client = new TMDbClient("<API KEY>");
            var People = client.SearchPersonAsync(ActorName).Result;
            int id = default(int);
            foreach (var person in People.Results)
            {
                id = person.Id;
                if (person.ProfilePath == null)
                {
                    ThumbPhotoPath = ImgPath + "JohnWayneSml.png";
                    FullPhotoPath = ImgPath + "JohnWayneBig.png";

                }
                else
                {
                    ThumbPhotoPath = ImgURL + "w45" + person.ProfilePath;
                    FullPhotoPath = ImgURL + "original" + person.ProfilePath;
                }


                if (!imgResults.Images.ContainsKey(ThumbPhotoPath))
                    imgResults.Images.Add(ThumbPhotoPath, LoadImage(ThumbPhotoPath));
                ListViewItem item = new ListViewItem();
                item.ImageKey = ThumbPhotoPath;
                item.Tag = person;
                item.SubItems.Add(person.Name);
                PeopleLV.Items.Add(item);
                

            }
        }



        private void PeopleLV_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (PeopleLV.SelectedItems.Count <= 0)
                return;

            int i = PeopleLV.SelectedIndices[0];
            //var  foundPerson = (FoundPerson) PeopleLV.Items[i].Tag;
            FoundPerson foundPerson = PeopleLV.Items[i].Tag;


            MessageBox.Show(foundPerson.);
        }

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Top Expert 2016

Commented:
did you try to use Person instead of FoundPerson on selection?

you would need a cast but if you stored a 'Person' in the tag you should be able to retrieve a 'Person'.

if you want to retrieve a FoundPerson from Tag, Person and FoundPerson must be correctly related. either Person is derived from FoundPerson (what sounds queer) or there is an appropriate constructor which turns a Person to a FoundPersons.

Sara

Commented:
Is there a reason you commented out the cast:
//var  foundPerson = (FoundPerson) PeopleLV.Items[i].Tag;
FoundPerson foundPerson = PeopleLV.Items[i].Tag;

Open in new window


Tag is an object type so it can hold ANYTHING. So you need to cast from an object back to the appropriate type to be able to access the properties. The commented-out line looks right at first glance, at least syntantically:
var  foundPerson = (FoundPerson) PeopleLV.Items[i].Tag;

Open in new window


If you're getting an error when trying to cast, then it probably means it's not a "FoundPerson" object. Maybe it's just Person or something. You can just put a breakpoint on that line and hover over the Tag property to see the true type.

Author

Commented:
There is a database object "person" & "Person" doesn't exist

var  foundPerson = (FoundPerson) PeopleLV.Items[i].Tag;

Open in new window


Hover over tag gives

Tag.jpg
And
System.InvalidCastException
  HResult=0x80004002
  Message=Unable to cast object of type 'TMDbLib.Objects.Search.SearchPerson' to type 'FilmsDB.FoundPerson'.
  Source=FilmsDB

Open in new window


That's why I thought I needed to create a new Object

SearchPerson person = PeopleLV.Items[i].Tag;

Open in new window


Also gives casting errors
Commented:
Short answer, try:
var person = (SearchPerson)PeopleLV.Items[i].Tag;

Open in new window


Explanation:
"var" is just a compiler shortcut. The full, true syntax is:
SearchPerson person = (SearchPerson)PeopleLV.Items[i].Tag;

Open in new window


But "var" just lets you say, "Hey, compiler. I've already told you what kind of value is going into this variable, so when you're compiling, can you just change 'var' to 'SearchPerson' or whatever kind of value the code indicates it will be? Thanks!"

So the important CASTING part is the part in parentheses. So look at this:
string xyz = "Hello world!";
object who_knows = xyz;

Open in new window


At this point, you have a generic object called "who_knows" that contains a string value. Now:
string abc = who_knows;

Open in new window


That is not casting, that's just trying to assign an object to a string, so that will throw a compiler error because strings can go into objects, but objects cannot go into strings (it's the old - all ravens are birds, but not all birds are ravens). Casting requires the value in parentheses (there's also an "as" operator but that's a topic for another time):
string abc = (string)who_knows;

Open in new window


Or you can use the "var" compiler shortcut to cut down on your code, but the important part is the (string) cast.
var abc = (string)who_knows;

Open in new window


What you're seeing in this scenario is that you were just trying to cast using the wrong type of value.

So instead of:
var person = (FoundPerson)PeopleLV.Items[i].Tag;

...it should have been:
var person = (SearchPerson)PeopleLV.Items[i].Tag;

...because the object in Tag was actually a SearchPerson object. The error you got:
Message=Unable to cast object of type 'TMDbLib.Objects.Search.SearchPerson' to type 'FilmsDB.FoundPerson'

...was because trying to cast it as FoundPerson made the system try to convert from the value it WAS (SearchPerson) to the value type you asked for (FoundPerson) and it couldn't do it.

Author

Commented:
Thanx for the Explanation possibly more helpful than just a  solution

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial