我使用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?
答案 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列(id
和value
)。
这是代码(我没有介绍删除):
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);
}
}
}
如果您测试它,您会看到插入和更新都满足您的问题请求。另外,请注意性能改进,因为不会在每次操作时重新创建数据表。