Vanonckelen Dieter
Vanonckelen Dieter

Reputation: 64

Casting mistake

Currently, in course, I am trying to check the LandCode from the class Landen to get the cities from the selectedItem land, but I am parsing something wrong.

public partial class Landen
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Landen()
    {
        this.Steden = new HashSet<Steden>();
        this.Talen = new HashSet<Talen>();
    }

    public string LandCode { get; set; }
    public string Naam { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Steden> Steden { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Talen> Talen { get; set; }
}



public MainWindow()
{
    InitializeComponent();
    var context = new LandenStedenTalenEntities();
    landenListBox.ItemsSource = (from Landen in context.Landen select Landen.Naam).ToList();
}

private void landenListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    using (var entities = new LandenStedenTalenEntities())
    {
        List<string> steden = new List<string>();
        var landcode = ((Landen)landenListBox.SelectedItem).LandCode.ToString();
        var gekozenland = entities.Landen.Find(landcode);

        foreach(var stad in gekozenland.Steden)
        {
            steden.Add(stad.Naam);
        }
        stedenInLandenListBox.ItemsSource = steden.ToList();
    }
}

Exception:

Unable to cast object of type 'System.String' to type 'TestEFDieter.Landen'.

I want to add them to a list and show them in a second Listbox. Can anyone help me out? Thank you.

enter image description here

Upvotes: 1

Views: 77

Answers (2)

mrogal.ski
mrogal.ski

Reputation: 5920

I would suggest you modify the code inside of the constructor so that the landenListBox will contain actual Landen object and displays only the Naam as it's item.

Change the code in the constructor to this:

public MainWindow()
{
    InitializeComponent();
    var context = new LandenStedenTalenEntities();
    landenListBox.ItemsSource = context.Landen.ToList();
    landenListBox.DisplayMemberPath = "Naam";
}

Adding DisplayMemberPath will inform ListBox to display that particular property as an item instead of calling ToString() method on that object.

Now in your later code you do not have to change much, just remove ToList() and since you're using EntityFramework you should insert the whole model in it's Find() method but it's useless since you already have that object loaded. You can just retrieve stad from it directly and display it in the same way Landen is displayed:

private void landenListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var landen = landenListBox.SelectedItem as Landen; // safe cast just in case
    if (landen != null && landen.Steden != null ) // null checks
    {
        stedenInLandenListBox.ItemsSource = landen.Steden.ToList(); // in case it's proxy object
        stadenInLandenListBox.DisplayMemberPath = "Naam";
    }
}

Upvotes: 1

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

I suppose you want to get that instance of Landen which corresponds the selected item in your list. As the elements in the listbox are just strings that represent the Naam-property of every Landen, you could simply iterate your list of Landen and get that one with the desired Naam:

var selectedLanden = landenList.FirstOrDefault(x => x.Naam == landenListBox.SelectedItem);
if(selectedLanden != null)
{
    var landCode = selectedLanden.LandCode;
    // ...
}

However as selectedLanden already is an instance of Landen, you won´t need to find it again by its LandCode. Thus your code boils donw to this:

List<string> steden = new List<string>();
var selectedLanden = landenList.FirstOrDefault(x => x.Naam == landenListBox.SelectedItem);
if(selectedLanden != null)
{
    foreach(var stad in selectedLanden.Steden)
    {
        steden.Add(stad.Naam);
    }
}
stedenInLandenListBox.ItemsSource = steden.ToList();

or a bit shorter:

stedenInLandenListBox.ItemsSource = selectedLanden.SelectMany(x => x.Steden.Select(y => y.Naam)).ToList();

For this to work you of course have to store a reference to the list of Landen somewehere in your class:

class MainWindow
{
    List<Landen> landenList;
    public MainWindow()
    {
        InitializeComponent();
        this.landenList = new LandenStedenTalenEntities();
        landenListBox.ItemsSource = (from Landen in this.landenList select Landen.Naam).ToList();
    }
}

Upvotes: 1

Related Questions