铸造错误

Casting mistake

目前,当然,我正在尝试从 class Landen 检查 LandCode 以从 selectedItem 土地获取城市,但我正在解析出了点问题。

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();
    }
}

异常:

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

我想将它们添加到列表中并在第二个列表框中显示它们。 谁能帮我吗?谢谢。

我想您想要获取 Landen 的实例,它对应于您列表中的所选项目。由于列表框中的元素只是表示每个 LandenNaam-属性 的字符串,您可以简单地迭代 Landen 列表并获得所需的那个Naam:

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

然而,由于 selectedLanden 已经 Landen 的一个实例,您不需要通过它的 LandCode 再次找到它。因此,您的代码会变成这样:

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();

或更短一点:

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

为此,您当然必须在 class:

的某个地方存储对 Landen 列表的引用
class MainWindow
{
    List<Landen> landenList;
    public MainWindow()
    {
        InitializeComponent();
        this.landenList = new LandenStedenTalenEntities();
        landenListBox.ItemsSource = (from Landen in this.landenList select Landen.Naam).ToList();
    }
}

我建议您修改构造函数内部的代码,以便 landenListBox 将包含实际的 Landen 对象并仅显示 Naam 作为它的项目。

将构造函数中的代码更改为:

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

添加 DisplayMemberPath 将通知 ListBox 将该特定 属性 显示为一个项目,而不是对该对象调用 ToString() 方法。

现在在你以后的代码中你不需要做太多改变,只需删除 ToList() 并且因为你正在使用 EntityFramework 你应该将整个模型插入它的 Find() 方法但它没用,因为你已经加载了那个对象。您可以直接从中检索 stad 并以与显示 Landen 相同的方式显示它:

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";
    }
}