【问题标题】:Casting mistake铸造错误
【发布时间】:2018-02-07 08:58:30
【问题描述】:

目前,当然,我正在尝试从 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();
    }
}

例外:

无法将“System.String”类型的对象转换为“TestEFDieter.Landen”类型。

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

【问题讨论】:

  • 你的错误在哪里?
  • var landcode = ((Landen)landenListBox.SelectedItem).LandCode.ToString();附加信息:无法将“System.String”类型的对象转换为“TestEFDieter.Landen”类型。
  • 你想用这个.ToString().ToList(); 达到什么目的? String 已经是一个“char 数组”,你可以通过调用 indexers 来遍历它。
  • 不假思索地找东西叫绝望-_-'
  • SelectedItem 显然包含一个字符串,它不能转换为Landen。我们不知道 Landen 是什么,也不知道您如何通过您在列表框中选择的任何内容来获取该类的实例。

标签: c# wpf casting listbox entity


【解决方案1】:

我建议您修改构造函数内部的代码,以便 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";
    }
}

【讨论】:

  • 工作就像一个魅力和很好的解释,谢谢先生!竖起大拇指
【解决方案2】:

我想你想获得Landen 的实例,它对应于列表中的选定项目。由于列表框中的元素只是代表每个Landen 的Naam 属性的字符串,因此您可以简单地迭代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();

为此,您当然必须在课堂上存储对 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 的工作方式是我发布它的方式,我只想在第二个列表框中显示带有选定土地的 LandCode 的城市
  • 请在您的问题中准确显示错误发生的位置
  • 感谢您的评论先生!竖起大拇指
猜你喜欢
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-20
相关资源
最近更新 更多