简体   繁体   中英

Select a DataRow in a DataGridView after creating new row

I use a PostgreSQL view to display data in a DataGridView :

dataSource = new BindingSource();
dataSource.DataSource = Program.DB.GetView(dbView);  // returns a DataTable
dgData.DataSource = dataSource;

Now, after I added a record using a PostgreSQL function, I refresh the data in the grid (I don't call Rows.Add() on the DataGridView :

protected void RefreshData() {
    dataSource.DataSource = Program.DB.GetView(dbView);
}

The insertion function of PostgreSQL returns the ID of the inserted row, so I know the ID (which is primary key) and want to set Selected to true in the DataGridView . The row can be anywhere in the set, because the view is sorted by name, not ID. I reckon I could do that by cycling over all rows and set the Selected when I found it, but this could become slow on large datasets.

Is there a way to somehow bind the rows of the datasource to the datagrid?

Add an event handler to the ListChanged event:

dataSource.ListChanged += dataSource_ListChanged;

Here is the event handler definition:

void dataSource_ListChanged(object sender, ListChangedEventArgs e)
{
    if (dgData.Rows.Count > 0)
        dgData.CurrentCell = dgData.Rows[e.NewIndex].Cells[0];
}

[UPDATE]

As I also suggested in the comments, maybe you should not repopulate the data source on each insert (or update). To demonstrate my point, I'll post a code sample which uses a DataGridView , 2 TextBoxes and 2 Button s (for insert and update) and a SqlDataAdapter . The SQL table has 2 columns ( id and value ).

Here's the code (I didn't cover the deletion):

public partial class Form1 : Form
{
    static BindingSource dataSource;
    static string dbView = "default";

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        dgData.MultiSelect = false;
        dataSource = new BindingSource();
        dataSource.ListChanged += dataSource_ListChanged;
        RefreshData();
        dgData.DataSource = dataSource;
        dgData.Sort(dgData.Columns[1], ListSortDirection.Ascending);
    }

    void dataSource_ListChanged(object sender, ListChangedEventArgs e)
    {
        if (dgData.Rows.Count > 0)
            dgData.CurrentCell = dgData.Rows[e.NewIndex].Cells[0];
    }

    protected void RefreshData()
    {
        dataSource.DataSource = DB.GetView(dbView);
    }

    private void insert_Click(object sender, EventArgs e)
    {
        DB.Insert(textBox1.Text);
        RefreshData();
    }

    private void update_Click(object sender, EventArgs e)
    {
        DB.UpdateRandomRow(textBox2.Text);
        RefreshData();
    }
}

class DB
{
    static DataTable dt;
    static string conStr = "yourConnectionString";
    static SqlDataAdapter _adapter;
    static Random r = new Random(10);

    public static SqlDataAdapter CreateSqlDataAdapter(SqlConnection connection)
    {
        _adapter = new SqlDataAdapter();
        _adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;

        _adapter.SelectCommand = new SqlCommand(
            "SELECT * FROM test", connection);
        _adapter.InsertCommand = new SqlCommand(
            "INSERT INTO test (value) " +
            "VALUES (@value)", connection);
        _adapter.UpdateCommand = new SqlCommand(
            "UPDATE test SET [value] = @value " +
            "WHERE id = @id", connection);
        _adapter.InsertCommand.Parameters.Add("@value",
            SqlDbType.NVarChar, 50, "value");
        _adapter.UpdateCommand.Parameters.Add("@id",
            SqlDbType.Int, 4, "id").SourceVersion = DataRowVersion.Current;
        _adapter.UpdateCommand.Parameters.Add("@value",
            SqlDbType.NVarChar, 50, "value").SourceVersion = DataRowVersion.Current;

        return _adapter;
    }

    // random update, to demonstrate dynamic
    // repositioning
    public static DataTable UpdateRandomRow(string value)
    {
        var currentRandom = r.Next(dt.Rows.Count);
        dt.Rows[currentRandom].SetField<string>(1, value);
        using (var con = new SqlConnection(conStr))
        {
            con.Open();
            _adapter = CreateSqlDataAdapter(con);
            _adapter.Update(dt);
        }
        return dt;
    }

    internal static DataTable GetView(string dbView)
    {
        if (dt == null)
        {
            dt = new DataTable();
            using (var con = new SqlConnection(conStr))
            {
                con.Open();
                _adapter = CreateSqlDataAdapter(con);
                _adapter.Fill(dt);
            }
        }
        return dt;
    }

    internal static void Insert(string value)
    {
        if (dt == null)
            GetView("");
        var dr = dt.NewRow();
        dr[1] = value;
        dt.Rows.Add(dr);
        using (var con = new SqlConnection(conStr))
        {
            con.Open();
            _adapter = CreateSqlDataAdapter(con);
            _adapter.Update(dt);
        }
    }
}

If you test it, you'll see that the request from your question is satisfied for both insert and update. Also, please note the performance improvement, as the data table is not recreated on each operation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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