创建新行后,在DataGridView中选择DataRow

时间:2013-03-01 09:07:17

标签: c# postgresql datagridview

我使用PostgreSQL视图在DataGridView

中显示数据
dataSource = new BindingSource();
dataSource.DataSource = Program.DB.GetView(dbView);  // returns a DataTable
dgData.DataSource = dataSource;

现在,在我使用PostgreSQL函数添加记录后,我刷新了网格中的数据(我没有在Rows.Add()上调用DataGridView

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

PostgreSQL的插入函数返回插入行的ID,因此我知道ID(主键),并想在Selected中将true设置为DataGridView。该行可以是集合中的任何位置,因为视图按名称排序,而不是ID。我认为我可以通过循环遍历所有行并在找到它时设置Selected,但在大型数据集上这可能会变慢。

有没有办法以某种方式将数据源的行绑定到datagrid?

1 个答案:

答案 0 :(得分:1)

ListChanged事件添加事件处理程序:

dataSource.ListChanged += dataSource_ListChanged;

以下是事件处理程序定义:

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

<强> [UPDATE]

正如我在评论中所建议的那样,也许你不应该在每个插入(或更新)上重新填充数据源。为了证明我的观点,我将发布使用DataGridView,2 TextBoxes和2 Button s(用于插入和更新)和SqlDataAdapter的代码示例。 SQL表有2列(idvalue)。

这是代码(我没有介绍删除):

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);
        }
    }
}

如果您测试它,您会看到插入和更新都满足您的问题请求。另外,请注意性能改进,因为不会在每次操作时重新创建数据表。