Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从datagridview中选定行中的值的ID获取名称_C#_.net_Sql Server_Winforms - Fatal编程技术网

C# 从datagridview中选定行中的值的ID获取名称

C# 从datagridview中选定行中的值的ID获取名称,c#,.net,sql-server,winforms,C#,.net,Sql Server,Winforms,我在gridview中隐藏了Author\u ID和Publisher\u ID。我希望当我单击一行时,Author和Publisher组合框文本填充选定的行值。行中有publisher和author id作为外键,但我想在组合框文本中显示它们的名称。如何访问它们 private void gridViewBook_CellContentClick(object sender, DataGridViewCellEventArgs e) { gridViewBo

我在gridview中隐藏了Author\u ID和Publisher\u ID。我希望当我单击一行时,Author和Publisher组合框文本填充选定的行值。行中有publisher和author id作为外键,但我想在组合框文本中显示它们的名称。如何访问它们

    private  void gridViewBook_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {

        gridViewBook.CurrentRow.Selected = true;

        txtID.Text = gridViewBook.Rows[e.RowIndex].Cells["BOOK_ID"].FormattedValue.ToString();
        txtISBN.Text = gridViewBook.Rows[e.RowIndex].Cells["ISBN"].FormattedValue.ToString();
        txtName.Text = gridViewBook.Rows[e.RowIndex].Cells["BOOK_NAME"].FormattedValue.ToString();
        txtPage.Text = gridViewBook.Rows[e.RowIndex].Cells["PAGE"].FormattedValue.ToString();
        txtLang.Text = gridViewBook.Rows[e.RowIndex].Cells["LANGUAGE"].FormattedValue.ToString();
        comboBoxAuthor.Text= gridViewBook.Rows[e.RowIndex].Cells["AUTHOR_ID"].FormattedValue.ToString();
        
        comboBoxPublisher.Text = gridViewBook.Rows[e.RowIndex].Cells["PUBLISHER_ID"].FormattedValue.ToString();
    }
我只能访问他们的ID。 我像这样填充组合框

    private void fillAuthorBox()
    {
        conn.Open();

        SqlCommand cmd = new SqlCommand("SELECT * FROM AUTHOR ", conn);
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        DataTable dt = new DataTable();
        da.Fill(dt);

        comboBoxAuthor.ValueMember = "AUTHOR_ID";
        comboBoxAuthor.DisplayMember = ("AUTHOR_FULLNAME");
        comboBoxAuthor.DataSource = dt;

        conn.Close();
    }

    private void fillPublisherBox()
    {
        conn.Open();

        string query = " SELECT * FROM PUBLISHER ";
        SqlCommand cmd = new SqlCommand(query, conn);
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        DataTable dt = new DataTable();
        da.Fill(dt);

        comboBoxPublisher.ValueMember = "PUBLISHER_ID";
        comboBoxPublisher.DisplayMember = "PUBLISHER_NAME";
        comboBoxPublisher.DataSource = dt;

        conn.Close();

    }

我首先看的是
fillAuthorBox()
fillPublisherBox()
。在某些地方,您有调用这些方法的代码。我们在问题中看不到这一点,因此我将假设它是一个通用的表单加载方法,如下所示:

void form_Load(...)
{
    fillAuthorBox();
    fillPublisherBox();
}
void form_Load(...)
{
    comboBoxAuthor.ValueMember = "AUTHOR_ID";
    comboBoxAuthor.DisplayMember = "AUTHOR_FULLNAME";
    comboBoxAuthor.DataSource = getAuthorNames();

    comboBoxPublisher.ValueMember = "PUBLISHER_ID";
    comboBoxPublisher.DisplayMember = "PUBLISHER_NAME";
    comboBoxPublisher.DataSource = getPublisherNames();
}
我们可以做得更好。这些方法中存在一些常见错误,我将在下面纠正这些错误:

//only re-use the connection string, NOT the whole connection object
private connString As String = "connection string here";

//return a value, don't touch any form controls
// even better if these methods are moved to a different class
public DataTable getAuthorNames()
{        
    using (var conn = new SqlConnection(connString))
    // Don't SELECT * if you don't need all the fields!
    using (var cmd = new SqlCommand("SELECT AUTHOR_ID, AUTHOR_FULLNAME FROM AUTHOR ", conn))
    using (var da = new SqlDataAdpater(cmd))
    { 
        var dt = new DataTable();
        da.Fill(dt); // Fill() automatically opens and closes the connection object
        return dt;
    } 
    //using blocks make sure your items are fully disposed when the block closes, 
    // **even if an exception is thrown!**
}

public DataTable getPublisherNames()
{
    ​using (var conn = new SqlConnection(connString))
    using (var cmd = new SqlCommand("SELECT PUBLISHER_ID, PUBLISHER_NAME FROM PUBLISHER", conn))
    using (var da = new SqlDataAdpater(cmd))
   ​ { 
        ​var dt = new DataTable();
       ​ da.Fill(dt);
       ​ return dt;
   ​ }     
}
现在,我的原始表单_Load()如下所示:

void form_Load(...)
{
    fillAuthorBox();
    fillPublisherBox();
}
void form_Load(...)
{
    comboBoxAuthor.ValueMember = "AUTHOR_ID";
    comboBoxAuthor.DisplayMember = "AUTHOR_FULLNAME";
    comboBoxAuthor.DataSource = getAuthorNames();

    comboBoxPublisher.ValueMember = "PUBLISHER_ID";
    comboBoxPublisher.DisplayMember = "PUBLISHER_NAME";
    comboBoxPublisher.DataSource = getPublisherNames();
}

从这里开始,我们可以继续在有人单击网格中的某一行时选择正确的条目。为此,我们不想设置
Text
属性,而是想更改所选的项目。因为我们知道
ValueItem
,所以可以通过
SelectedValue
属性来实现

private  void gridViewBook_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    gridViewBook.CurrentRow.Selected = true;

    txtID.Text = gridViewBook.Rows[e.RowIndex].Cells["BOOK_ID"].FormattedValue.ToString();
    txtISBN.Text = gridViewBook.Rows[e.RowIndex].Cells["ISBN"].FormattedValue.ToString();
    txtName.Text = gridViewBook.Rows[e.RowIndex].Cells["BOOK_NAME"].FormattedValue.ToString();
    txtPage.Text = gridViewBook.Rows[e.RowIndex].Cells["PAGE"].FormattedValue.ToString();
    txtLang.Text = gridViewBook.Rows[e.RowIndex].Cells["LANGUAGE"].FormattedValue.ToString();

    comboBoxAuthor.SelectedValue = gridViewBook.Rows[e.RowIndex].Cells["AUTHOR_ID"].Value;        
    comboBoxPublisher.SelectedValue = gridViewBook.Rows[e.RowIndex].Cells["PUBLISHER_ID"].Value;
}

但是在这里要小心!我对WinForms有点不习惯,我不记得这对于不匹配的类型有多宽容。组合框
ValueMember
可能是一个
int
DataGridViewCell
,但是我们使用
字符串来设置
SelectedValue
,这可能不起作用。您可能需要将字符串转换回int,或者查找值的索引来更新SelectedIndex属性。

不要在任何地方重复使用相同的SqlConnection(
conn
)。它干扰了一种称为连接池的功能,因此(在
使用
块中)大多数查询都会遇到这种情况。另外,
.Fill()
方法已经为您打开和关闭了连接。最后,构建数据访问方法以返回数据比直接更新控件要好得多。让调用这些方法的代码更新表单中的控件。是否考虑过在每个文本框中添加一个
数据绑定
?类似于…
txtISBN.DataBindings.Add(“Text”,gridViewBook.DataSource,“ISBN”)…这将消除网格
CellContentClick
事件中的所有代码,并完成相同的任务。非常感谢。通常我不会为Windows窗体编写代码,但这是我必须完成的项目的一部分。因为我对这门学科知之甚少,所以我需要帮助,尽管这很容易。谢谢你的帮助,它运行得很顺利@乔尔科霍恩