当有两个oledbadapter填充命令时,ListBox项被item.tostring()(?)替换

本文关键字:项被 ListBox item tostring 替换 填充 两个 oledbadapter 命令 | 更新日期: 2023-09-27 18:12:24

我对stackoverflow的第一个问题,因为我还没有找到任何解决方案:

我正在研究一个简单的密码显示工具,它从MS Access DB获取数据(没有适当的DB可用…)

Access DB有两个表。一个PC表和一个密码子表,通过MAC地址链接。

程序在列表框中显示一个键/值列表,其中包含通过oledb检索到的所有PC名称。

键为PC名,值为MAC地址。

        void cmdGetPCs()
    {
        OleDbDataAdapter daPCs = new OleDbDataAdapter();
        OleDbConnection vcon = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;data source=H:'XXX'XXX'MYACCESSFILE.accdb;Jet OLEDB:Database Password=[REDACTED]");
        const string q = "SELECT SISSI & ' (' & IP & ') - ' & DESCRIPTION as LONGDESCR, MAC from PC_LIST WHERE active = true order by sissi, ip"; //use & instead of + to have blankspace instead of null values for displaying PCs without Sissi because CONCAT doesn't work (MS Access....)
        vcon.Open();
            daPCs.SelectCommand = new OleDbCommand(q, vcon);
        vcon.Close();
        DataSet dsPC = new DataSet("PCs");
        daPCs.MissingSchemaAction = MissingSchemaAction.AddWithKey;
        daPCs.Fill(dsPC, "tblPCs");
        DataTable dtPC = dsPC.Tables["tblPCs"];
        var PCList = new List<PCInfo>();
        foreach (DataRow dtRow in dtPC.Rows)
        {
            PCList.Add(new PCInfo() { LONGDESCR = dtRow["LONGDESCR"].ToString(), MAC = dtRow["MAC"].ToString()  });
        }
        lstPCs.DisplayMember = "LONGDESCR";
        lstPCs.ValueMember = "MAC";
        lstPCs.DataSource = PCList;
    }

好了,我有一个列表,里面都是个人电脑的描述。现在,当我从Listbox中选择一个项目时,我在同一个窗口中有一个datagridview元素,应该用密码信息填充:

    void ListBox1SelectedIndexChanged(object sender, EventArgs e)
    {
        groupBox1.Text = lstPCs.GetItemText(lstPCs.SelectedItem);
        string x = lstPCs.GetItemText(lstPCs.SelectedValue);
        //Dataset_get(x);
    }

只要将Dataset_get注释掉,这仍然可以正常工作。第一行以组框头的形式显示项目框的可见键,字符串x为所选项目的MAC地址(=ItemList值)

一旦我激活Dataset_get(x)并启动程序,ListBox就会被填充,但似乎所有项目都被item.toString()占位符所取代。

列表框看起来就像:

  • myprogramname。MainForm + PCInfo
  • myprogramname。MainForm + PCInfo
  • myprogramname。MainForm + PCInfo
  • myprogramname。MainForm + PCInfo
  • myprogramname。MainForm + PCInfo
  • 等。

indexchange的前两行(组框和字符串x)仍然可以正常工作并显示正确的值。此外,Dataset_get本身工作良好,并填充Datagridview。所以我可以有一个用户可读的列表框没有填充的数据网格视图一个破碎的列表框与填充的数据网格视图…显然,我需要一个具有填充数据网格视图的可读列表框;)

我缩小了问题在Dataset_get点,它开始被打破一旦填充线的数据网格视图数据检索被称为:

    private void Dataset_get(string mymac)
    {
        OleDbDataAdapter daPass = new OleDbDataAdapter();
        OleDbConnection vconp = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;data source=H:'XXX'XXX'MYACCESSFILE.accdb;Jet OLEDB:Database Password=[REDACTED]");
        string qp = "";
        switch (mypermissions)
        {
            case "ADMIN":
                qp = "SELECT USER_TYPE, HAS_ADMIN, USER_NAME, PASSWORD, ID FROM PASSWORDS WHERE ID = '" + mymac + "' ORDER BY user_type";break;
            case "USER":
                qp = "SELECT p.USER_TYPE, p.HAS_ADMIN, p.USER_NAME, p.PASSWORD, p.ID FROM PASSWORDS p, PC_LIST pc WHERE p.ID = '" + mymac + "' and p.ID = pc.MAC and (pc.x_plant like '%USER%' or (ucase(p.user_type) not like '%ADMIN%')) ORDER BY p.user_type";break;
            default: break;
        }
        vconp.Open();
            daPass.SelectCommand =  new OleDbCommand(qp, vconp);
        vconp.Close();
        DataSet dsPass = new DataSet("Passwords");
        daPass.MissingSchemaAction = MissingSchemaAction.AddWithKey;
        daPass.Fill(dsPass,"tblPass"); //REPLACEMENT OF LIST ITEMS IS TRIGGERED BY THIS LINE
        DataTable dtPass = dsPass.Tables["tblPass"];
        dataGridView1.DataSource = dtPass;
    }

请帮帮我…提前感谢!

PS: datagridview是在一个组框,而列表框不是,但这没有任何区别我猜。

当有两个oledbadapter填充命令时,ListBox项被item.tostring()(?)替换

在Reza Aghaeis的帮助下解决了这个问题

获取列表框项的值
    public static class ListControlExtensions
    {
        public static object GetItemValue(this ListControl list, object item)
        {
            if (item == null)
                throw new ArgumentNullException("item");
            if (string.IsNullOrEmpty(list.ValueMember))
                return item;
            var property = TypeDescriptor.GetProperties(item)[list.ValueMember];
            if (property == null)
                throw new ArgumentException(
                    string.Format("item doesn't contain '{0}' property or column.",
                    list.ValueMember));
            return property.GetValue(item);
        }
    }
//.........................................
    void cmdGetPCs()
    {
        const string q = "SELECT SISSI & ' (' & IP & ') - ' & DESCRIPTION as LONGDESCR, MAC from PC_LIST WHERE active = true order by sissi, ip"; //use & instead of + to have blankspace instead of null values for displaying PCs without Sissi because CONCAT doesn't work (MS Access....)
        OleDbDataAdapter da = new OleDbDataAdapter();
        DataSet ds = new DataSet();
        vcon.Open();
            da.SelectCommand = new OleDbCommand(q, vcon);
        vcon.Close();
        da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
        da.Fill(ds, "tblPCs");
        DataTable dtPC = ds.Tables["tblPCs"];
        foreach (DataRow dtRow in dtPC.Rows)
        {
            lstPCs.Items.Add(new KeyValuePair<String, String>(dtRow["LONGDESCR"].ToString(), dtRow["MAC"].ToString()));
        }
        lstPCs.DisplayMember = "Key";
        lstPCs.ValueMember = "Value";
    }
//.........................................
    private void Dataset_get(string mymac)
    {
        string qp = "";
        switch (mypermissions)
        {
            case "ADMIN":
                qp = "SELECT USER_TYPE, HAS_ADMIN, USER_NAME, PASSWORD FROM PASSWORDS WHERE ID = '" + mymac + "' ORDER BY user_type";break;
            case "USER":
                qp = "SELECT p.USER_TYPE, p.HAS_ADMIN, p.USER_NAME, p.PASSWORD FROM PASSWORDS p, PC_LIST pc WHERE p.ID = '" + mymac + "' and p.ID = pc.MAC and (pc.x_plant like '%USER%' or (ucase(p.user_type) not like '%ADMIN%')) ORDER BY p.user_type";break;
            default: break;
        }
        OleDbDataAdapter dapass = new OleDbDataAdapter();
        DataSet dspass = new DataSet();
        vcon.Open();
            dapass.SelectCommand =  new OleDbCommand(qp, vcon);
        vcon.Close();
        dapass.MissingSchemaAction = MissingSchemaAction.AddWithKey;
        dapass.Fill(dspass,"tblPass");
        DataTable dtPass = new DataTable();
        dtPass = dspass.Tables["tblPass"];
        dataGridView1.DataSource = dtPass;
    }
//.........................................
    void ListBox1SelectedIndexChanged(object sender, EventArgs e)
    {
        groupBox1.Text = lstPCs.GetItemText(lstPCs.SelectedItem);
        string x = lstPCs.GetItemValue(lstPCs.SelectedItem).ToString();
        Dataset_get(x);
    }

OleDbConnection vcon是共享的