我有代码可以使用鼠标拖放来移动 datagridview 中的行,但是在关闭程序或更新表格后,所有内容都会重置。如何将数据放置保存到数据库中?
使用鼠标事件拖动行,同时将一个单元格值显示到标签中的代码。
运行后它会插入行
int dragRow = -1;
Label dragLabel = null;
private void dataGridView1_CellMouseDown(object sender,DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex<0 || e.RowIndex < 0) return;
dragRow = e.RowIndex;
if (dragLabel == null) dragLabel = new Label();
dragLabel.Text = dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString();
dragLabel.Parent = dataGridView1;
dragLabel.Location = e.Location;
}
private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && dragLabel != null)
{
dragLabel.Location = e.Location;
dataGridView1.ClearSelection();
}
}
private void dataGridView1_MouseUp(object sender, MouseEventArgs e)
{
var hit = dataGridView1.HitTest(e.X,e.Y);
int dropRow = -1;
if (hit.Type != DataGridViewHitTestType.None)
{
dropRow = hit.RowIndex;
if (dragRow >= 0 )
{
int tgtRow = dropRow + (dragRow > dropRow ? 1 : 0);
if (tgtRow != dragRow)
{
DataRow dtRow = DT.Rows[dragRow];
DataRow newRow = DT.NewRow();
newRow.ItemArray = DT.Rows[dragRow].ItemArray;
DT.Rows.Remove(dtRow);
DT.Rows.InsertAt(newRow, tgtRow);
dataGridView1.Refresh();
dataGridView1.Rows[tgtRow].Selected = true;
}
}
}
else { dataGridView2.Rows[dragRow].Selected = true;}
if (dragLabel != null)
{
dragLabel.Dispose();
dragLabel = null;
}
}
在表格中显示数据的代码:
command = new SqlCommand("select * from ustroystva", connection);
adapter.SelectCommand = command;
table.clear();
adapter.Fill(table);
dataGridViewl.DataSource = table;
dt = table;
adapter.Update (dt);
“向存储订单的表添加一个字段”的建议是一个很好的建议,但不仅仅是“任何”字段都可以。假设数据库仅包含三个项目。如果我们查询 Apple | Orange 并为它们分配“1”和“2”作为排序顺序,然后查询 Orange |香蕉并分配给他们“1”和“2”我们得到了什么?所以对我有用的是有一个基于时间的
Priority
字段用于排序顺序。
[Table("records"), DebuggerDisplay("{Name}")]
class Record
{
[PrimaryKey, Browsable(false)]
public string Guid { get; set; } = System.Guid.NewGuid().ToString();
public DateTime Created { get; set; } = DateTime.Now;
[Browsable(false)]
public DateTime Priority { get; set; } = DateTime.Now;
[ReadOnly(true)]
public string Name { get; set; } = string.Empty;
}
为了简单起见,假设我们使用
sqlite-net-pcl
而不是 System.Data.SQLite
,以便 DataGridView
可以使用简单的列表绑定。 (这与实际答案无关,只是更容易显示代码。)
BindingList<Record> Recordset { get; } = new BindingList<Record>();
[重新查询]按钮点击处理程序为:
buttonRequery.Click += async (sender, e) =>
{
Recordset.Clear();
using (var cnx = new SQLiteConnection(SQLitePath))
{
foreach (var item in cnx.Query<Record>("SELECT * FROM records ORDER BY Priority"))
{
Recordset.Add(item);
}
}
};
作为响应,在更新数据库记录之前,按顺序对优先级进行排序,并将它们应用到它们现在存在的新顺序中的项目。
dataGridView.MouseUp += (sender, e) =>
{
var hit = dataGridView.HitTest(e.X, e.Y);
int dropRow = -1;
if (hit.Type != DataGridViewHitTestType.None)
{
dropRow = hit.RowIndex;
if (dragRow >= 0)
{
int tgtRow = dropRow + (dragRow > dropRow ? 1 : 0);
if (tgtRow != dragRow)
{
var record = Recordset[dragRow];
Recordset.Remove(record);
Recordset.Insert(tgtRow, record);
dataGridView.Refresh();
dataGridView.Rows[tgtRow].Selected = true;
}
}
}
if (dragLabel != null)
{
dragLabel.Dispose();
dragLabel = null;
// Apply the sorted priorities to the items as they now stand in the list.
var priorities = Recordset.Select(_ => _.Priority).OrderBy(_=>_).ToArray();
for(int index = 0; index < priorities.Length; index++)
{
Recordset[index].Priority = priorities[index];
}
using (var cnx = new SQLiteConnection(SQLitePath))
{
cnx.UpdateAll(Recordset);
}
}
dataGridView.CurrentCell = hit.ColumnIndex == -1 || hit.RowIndex == -1 ?
null :
dataGridView[hit.ColumnIndex, hit.RowIndex];
};
示例
假设我们能够通过单击列标题进行短暂排序。作为测试序列,我们可以(短暂)按
Created
排序,然后(短暂)按 Name
排序,然后点击 [重新查询] 按钮以实际拖放后顺序检索数据库项目。
dataGridView.CellClick += (sender, e) =>
{
if(e.RowIndex == -1)
{
Record[] sorted;
if (dataGridView.Columns[nameof(Record.Created)].Index == e.ColumnIndex)
{
sorted = Recordset.OrderBy(_ => _.Created).ToArray();
}
else if (dataGridView.Columns[nameof(Record.Name)].Index == e.ColumnIndex)
{
sorted = Recordset.OrderBy(_ => _.Name).ToArray();
}
else return;
Recordset.Clear();
foreach (var item in sorted)
{
Recordset.Add(item);
}
}
};
因此,您可以通过将其优先级设置为 ((Apple.Priority) + (Banana.Priority)) / 2,在 Apple 和 Banana 之间插入
Grape
。
你明白了。