简体   繁体   English

从具有两种类型对象的列表中获取 ComboBox 选定值,并且组合框仅显示其中一种

[英]Get ComboBox selected value from a list which has two types of objects and the combobox is only showing one of them

I'm building a C# application in Windows Forms.我正在 Windows 窗体中构建 C# 应用程序。
I have a vehicle class and two derived classes car and motorbike.我有一个车辆类和两个派生类汽车和摩托车。
I then have the vehicles saved into a list.然后我将车辆保存到列表中。

Now I have a form where I want to show only the cars or only the motorbikes.现在我有一个表格,我只想显示汽车或摩托车。 In a main form there is a button "show cars" and another button "show motorbikes" and they will tell the other form which to list ("type" variable in code below).在主窗体中有一个按钮“显示汽车”和另一个按钮“显示摩托车”,它们会告诉另一个窗体要列出哪个(下面代码中的“类型”变量)。

In the show form I have a combobox which will show all the cars or motorbikes (only one, not both) that exist and when selecting one, there are textboxes that will show the info from that one.在展示表格中,我有一个ComboBox,它将显示所有存在的汽车或摩托车(仅一个,而不是两者),其中选择一个并且有一个文本框,它将显示那个信息。

To populate the combobox I use:要填充我使用的组合框:

foreach (Vehicle V in GetVehiclesList())
{
    if (type == "Car")
    {
        if (V.WhatIsIt() == "Car")
        {
            combobox.Items.Add(V.GetVehicleName());
        }
    }
    else if (type == "Motorbike")
    {
        if (V.WhatIsIt() == "Motorbike")
        {
            combobox.Items.Add(V.GetVehicleName());
        }
    }
}

Note: WhatIsIt() returns a string with the class' name.注意:WhatIsIt() 返回一个带有类名的字符串。

Now the problem is to get the selected vehicle in the combobox to show the info from that vehicle.现在的问题是在组合框中获取所选车辆以显示该车辆的信息。

If I wanted to show all the vehicles, I would use this:如果我想展示所有车辆,我会使用这个:

private void combobox_SelectedIndexChanged(object sender, EventArgs e)
{
    VehicleToShow = GetVehiclesList()[combobox.SelectedIndex];
    vehicle_name_textbox.Text = VehicleToShow.GetVehicleName();
    // and goes on
}

What this does is it gets the index number of the combobox item selected and goes get the vehicle in the list with that same position number.它的作用是获取所选组合框项的索引号,并获取列表中具有相同位置号的车辆。 It works because the vehicles are added to the combobox with same position/index as in the list.它起作用是因为车辆被添加到组合框中,其位置/索引与列表中的相同。 Therefore, it doesn't work for displaying only one of them (car or motorbike) because the position number in list will fail to be equal to the index in combobox.因此,它不适用于仅显示其中之一(汽车或摩托车),因为列表中的位置编号将无法与组合框中的索引相等。

So I used the folowing approach:所以我使用了以下方法:

private void combobox_SelectedIndexChanged(object sender, EventArgs e)
{
    VehicleToShow = null;
    int carposition = 0;
    int motorbikeposition = 0;
    int comboboxindex = combobox.SelectedIndex;

    foreach (Vehicle V in GetVehiclesList())
    {
        if (V.WhatIsIt() == "Car")
        {
            if (carposition == comboboxindex)
            {
                VehicleToShow = V;
            }
            else
            {
                carposition++;
            }
        }
        else if (V.WhatIsIt() == "Motorbike")
        {
            if (motorbikeposition == comboboxindex)
            {
                VehicleToShow = V;
            }
            else
            {
                motorbikeposition++;
            }
        }
    }

    vehicle_name_textbox.Text = VehicleToShow.GetVehicleName();
    // and goes on
}

While this seems to me to be something that should work, when using it, it won't display the info from the vehicle selected in the combobox.虽然在我看来这应该是可行的,但在使用它时,它不会显示来自组合框中所选车辆的信息。

How can I get it to work?我怎样才能让它工作?

Note: Placing each vehicle type in a different list is not an option.注意:不能将每种车辆类型放在不同的列表中。 Also, searching list for an object with same name as selected value is not best option since it won't work properly if it has two vehicles with same name.此外,搜索与所选值同名的对象列表也不是最佳选择,因为如果它有两辆同名的车辆,它将无法正常工作。 Ideally it would be something similar as the approach I tried to use.理想情况下,它与我尝试使用的方法类似。

Don't add the names of your objects to the list.不要将对象的名称添加到列表中。 Add the actual objects themselves instead;改为添加实际对象本身 then combobox.SelectedItem immediately contains everything you need without requiring any lookup at all, since it'll be the full object.然后combobox.SelectedItem立即包含您需要的所有内容,根本不需要任何查找,因为它将是完整的对象。

The filling of the data:数据的填写:

this.combobox.Items.Clear();
foreach (Vehicle veh in this.GetVehiclesList())
{
    // assuming "type" is a string variable filled up by some other selected value.
    if (!String.Equals(type, typeof(veh).ToString()))
        continue;
    this.combobox.Items.Add(veh);
}

Though derloopkat's suggestion of saving type as an actual Type so you can compare them directly is probably more efficient than string compares.尽管 derloopkat 建议将type保存为实际Type以便您可以直接比较它们可能比字符串比较更有效。 Avoid string compares in code;避免在代码中进行字符串比较; they are often an ugly programmer shortcut for something that can be done way more elegantly and efficiently internally.对于一些可以在内部更优雅、更高效地完成的事情,它们通常是一个丑陋的程序员捷径。

To make them show up in the list correctly, simply add the ToString() function in your vehicle class that returns the actual vehicle name:为了使它们正确显示在列表中,只需在您的车辆类中添加ToString()函数,该函数返回实际车辆名称:

public override String ToString()
{
    return this.GetVehicleName()
}

And finally, to retrieve the selected object and update your UI:最后,要检索选定的对象并更新您的 UI:

private void combobox_SelectedIndexChanged(Object sender, EventArgs e)
{
    // "as" is a "try cast": if the object is not the expected type it will become null.
    this.VehicleToShow = this.combobox.SelectedItem As Vehicle;
    if (this.VehicleToShow == null)
        return; // maybe add code to clear UI
    this.vehicle_name_textbox.Text = this.VehicleToShow.GetVehicleName();
    // fill in the rest
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM