如何在C#Windapp中使用Displayvalue和Displaymember在Combobox中检索数据 [英] How I Retrieve Data In Combobox Using Displayvalue And Displaymember In C# Windapp

查看:69
本文介绍了如何在C#Windapp中使用Displayvalue和Displaymember在Combobox中检索数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

void FillComboBoxRepair()
        {
            try
            {
                con.Open();
                s = "select * from Repair_Type";
                sd = new SqlCommand(s,con);

                sda = sd.ExecuteReader();
                while (sda.Read())
                {
                    string Repair_type = sda.GetString(1);
                    CB_Repair_type.Items.Add(Repair_type);
                }
                con.Close();
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

推荐答案

在你进一步发展之前,你想要改变的代码中有很多东西。

1)您有责任自行清理,因此如果没有正确处理它们,请不要创建SqlCommand对象。 使用块是最简单的方法。

2)不要使用SELECT * FROM和数字索引 - 总是指定你想要的字段,并使用他们的名字。当数据库发生变化并且你的应用程序失败时,它可以节省大量的时间,而且效率更高。

3)Combobox DisplayMember和ValueMember属性设计用于集合,所以当你刚才一次一个地添加字符串,它实际上不起作用。

尝试这样的事情:

There are quite a few things in that code you want to change before you go any further.
1) You are responsible for cleaning up after yourself, so don't create SqlCommand objects without Disposing of them properly. A using block is the easiest way.
2) Don't use "SELECT * FROM" and numeric indexes - always specify the fields you want, and use their names. It saves a lot of head scratching when the database changes and your app fails, and it's a lot more efficient.
3) The Combobox DisplayMember and ValueMember properties are designed to work with collections, so when you just add strings to the box one at a time, it doesn't really work.
Try something like this:
void FillComboBoxRepair()
    {
    try
        {
        con.Open();
        s = "SELECT ID, Description FROM Repair_Type";
        using (sd = new SqlCommand(s, con))
            {
            DataTable dt = new DataTable();
            using (SqlDataAdapter da = new SqlDataAdapter(sd))
                {
                da.Fill(dt);
                CB_Repair_type.DataSource = dt;
                CB_Repair_type.DisplayMember = "Description";
                CB_Repair_type.ValueMember = "ID";
                }
            }
        con.Close();
        }
    catch (Exception ex)
        {
        MessageBox.Show(ex.Message);
        }
    }



现在ComboBox显示Description并返回描述字符串的ID值。


Now the ComboBox displays the Description and returns the ID value for the description string.


首先,您必须将ComboBox的DataSource属性设置为包含具有命名公共属性的对象(类或结构)的实例的有效List(Collection,IEnumerable等)。 。



您将DisplayMember设置为您希望在UI中显示的属性名称(在源对象中);将ValueMember设置为您想要与ComboBox中的每个项目关联的Property Name。



当用户在运行时选择ComboBox中的Item时,您可以通过'SelectedValue属性访问与该项关联的ValueMember。



如果您从数据库的调用获得的是一组字符串,并且您使用这些字符串填充ComboBox.Items,就像现在一样,然后'DisplayMember和'ValueMember属性都只是空字符串;它们从未使用过。



以下是如何使用这些属性的示例:
First, you must set the DataSource Property of the ComboBox to some valid List (Collection, IEnumerable, etc.) containing instances of Objects (Class, or Struct) with named Public Properties.

You set the DisplayMember to the Property Name (in the source Object) you wish to appear in the UI; set the ValueMember to the Property Name whose Value you wish to be associated with each Item in the ComboBox.

When the user selects an Item in the ComboBox at run-time, you can access the ValueMember associated with that Item via the 'SelectedValue Property.

If all you get from your call to the Database is a set of strings, and you populate the ComboBox.Items with those strings, as you are doing now, then both 'DisplayMember and 'ValueMember properties are just empty strings; they are never used.

Here's an example of how those Properties are used:
// in some Class
public struct ComboStruct
{
    public string PublicString1 { set; get; }
    public string PublicString2 { set; get; }

    public ComboStruct(string s1, string s2) : this()
    {
        PublicString1 = s1;
        PublicString2 = s2;
    }
}

public List<ComboStruct> ComboData = new List<ComboStruct>();

// in a Method in the Class like a Form Load EventHandler:
private void Form1_Load(object sender, EventArgs e)
{
    // build the List
    for (int i = 0; i < 10; i++)
    {
        string s = i.ToString();
        ComboData.Add(new ComboStruct(string.Format("s1:{0}", s), string.Format("s2:{0}", s))); 
    }

    // set the DataSource to the List
    comboBox1.DataSource = ComboData;

    // set the Display/Value Members
    comboBox1.DisplayMember = "PublicString1";
    comboBox1.ValueMember = "PublicString2";
}

现在您可以为ComboBox定义'SelectedIndexChanged EventHandler并获取ValueMember:

Now you can define a 'SelectedIndexChanged EventHandler for the ComboBox and get the ValueMember:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    string vMember = comboBox1.SelectedValue.ToString();
    Console.WriteLine(vMember);
}

值得注意的是,当您获得'SelectedValue时,您将获得对您设置为'ValueMember的属性的值的引用。但是,ValueMember总是将价值装箱作为对象;要将它用作String,我们需要将其转换为String。

It is important to note that when you get the 'SelectedValue, you are getting a reference to the Value of the Property you set to be the 'ValueMember. But, the ValueMember is always going to be that 'Value "boxed" as an Object; to use it as a String, we need to cast it to a String.


这里有一个简单的例子。要使其运行,您必须向表单添加名为ExampleComboBox的ComboBox。

Here's a bare-bones example for you. To get it running you have to add a ComboBox named "ExampleComboBox" to the Form.
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        DataTable dt = new DataTable();

        dt.Columns.Add("ID", typeof(int));
        dt.Columns.Add("Name", typeof(string));

        DataRow row1 = dt.NewRow();
        row1["ID"] = 1;
        row1["Name"] = "First";
        dt.Rows.Add(row1);

        DataRow row2 = dt.NewRow();
        row2["ID"] = 2;
        row2["Name"] = "Second";
        dt.Rows.Add(row2);

        ExampleComboBox.ValueMember = "ID";
        ExampleComboBox.DisplayMember = "Name";
        ExampleComboBox.DataSource = dt;

        ExampleComboBox.SelectedValue = 1; // set the initial selection

        ExampleComboBox.SelectedIndexChanged += ExampleComboBoxSelectedIndexChanged;
    }

    private void ExampleComboBoxSelectedIndexChanged(object sender, EventArgs e)
    {
        int selectedID = (int)ExampleComboBox.SelectedValue; // get the current selection
    }
}





要将它与从数据库中读取的代码集成,您需要将记录读入一个对象,而不是ComboBox可用作DataSource的对象。我建议你使用DataTable。



另外一点,你的数据库访问代码有很多不太好的东西:

- 不要将连接,命令和读取器对象声明为类成员。在方法中声明它们 - 在方法中。

- 使用使用 -statements和所有一次性对象。这将使得关闭连接成为不必要的,并且在发生异常时将阻止它保持打开状态。目前,它将保持打开状态,因为它不会到达con.Close()行。同样,对于除连接之外的其他一次性对象,使用使用 -statement将确保在完成后释放已分配的资源。

- 使用抽象Db ***** - 基类或IDb ***** - 接口(如DbConnection,DbCommand,..)而不是像SqlConnection,SqlCommand等数据库系统特定的接口。看看< a href =https://msdn.microsoft.com/en-us/library/dd0w4a2z%28v=vs.110%29.aspx> DbProviderFactory [ ^ ]。



To integrate it with your code that reads from the database you need to read the records into an object than can be used as a DataSource by the ComboBox. I would recommend you to use a DataTable for that.

On a different note, there's a lot of not-so-good stuff about your database-access code:
- Don't declare the connection, command and reader objects as class members. Declare them where you need them - in the method.
- Use using-statements with all disposable objects. This will make it unneccessary to close the connection and will prevent it from staying open in case an exception occurs. Currently, it would stay open because it wouldn't reach the con.Close() line. Likewise for other disposable objects than the connection, using them with a using-statement will ensure you are freeing the allocated resources when you're done.
- Use the abstract Db*****-baseclasses or IDb*****-interfaces (like DbConnection, DbCommand,..) rather than the database-system specific ones like SqlConnection, SqlCommand etc. Take a look at DbProviderFactory[^].


这篇关于如何在C#Windapp中使用Displayvalue和Displaymember在Combobox中检索数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆