如何将选定的单元格添加到不同的 DataGridView 框中

How do I add selected cells into a different DataGridView box

[双击时从可用移动到选定][1]

我有 2 个数据网格视图,我想将用户点击的特定单元格从一个网格移动到另一个网格。

我试过了

private void availableFacilList_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
{
    var selectedMove = availableFacilList.Rows[e.RowIndex].Cells[0].Value.ToString();
    DataGridViewRow row = (DataGridViewRow)selectedFacilList.Rows[0].Clone();
    row.Cells[0].Value = selectedMove;
    selectedFacilList.Rows.Add(row);
}

图片附上它的外观 [1]: https://i.stack.imgur.com/qjWiX.png

这是您问题的粗略实现。使用代码作为基础,因为它包含基本逻辑并使其适应您的变量和事件处理程序。编码愉快!

DataTable DTAvailable, DTSelected;
internal void SetupGrid(Grid _grid, string _columnName)
{ //Add the columns  for the _grid object with the name _columnName}

internal void DoGridsLoad()
{ 
  DTSelected = LoadData();
  SetupGrid(Grid1, "Selected"); 
  Grid1.DataSource = DTAvailable;
  
  SetupGrid(Grid2, "Available");
  DTSelected = new DataTable();
  Grid2.DataSource = DTSelected;

}

internal void MoveToSelected(object sender, EventArgs e) //BTN Move to Selected
{ 
  DataRow toMove = DTAvailable[Grid1.CurrentRowIndex]; //locate Row
  DTSelected.Rows.Add(toMove);
  DTAvailable.Rows.Remove(toMove);
}

internal void MoveToAvailable(object sender, EventArgs e) //BTN Move to Available
{ 
  DataRow toMove = DTSelected[Grid2.CurrentRowIndex]; //locate Row
  DTAvailable.Rows.Add(toMove);
  DTSelected.Rows.Remove(toMove);
}

如评论中所述,如果第二个网格至少有一列,则发布的代码似乎有效。我相信这就是为什么在代码行抛出索引超出范围异常的原因……

DataGridViewRow row = (DataGridViewRow)selectedFacilList.Rows[0].Clone();

因为……selectedFacilList.Rows[0]……第零 (0) 行不存在。

对两个网格都使用 DataSource 可能会让事情变得更容易。在这种情况下,如果两个网格使用具有相同模式的两个不同 DataTables,那么您需要做的就是将选定的行从一个 DataTable 移动到另一个,网格将更新自动。

首先,我们要制作两 (2) 个具有相同架构的数据 table。它将有一个 string 列,我们将使用这些 table 将选定的行从一个 table 移动到另一个 table ,反之亦然。

创建这些 table 并用左侧网格的一些测试数据填充它们可能看起来类似于您的图片显示的内容,但右侧的网格至少有一列。

DataTable AvailableDT;
DataTable SelectedDT;

public Form1() {
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
  AvailableDT = GetEmptyDT();
  SelectedDT = GetEmptyDT();
  FillTableWithData(AvailableDT);
  availableFacilGrid.DataSource = AvailableDT;
  selectedFacilGrid.DataSource = SelectedDT;
}

private DataTable GetEmptyDT() {
  DataTable dt = new DataTable();
  dt.Columns.Add("Group", typeof(string));
  return dt;
}

private void FillTableWithData(DataTable dt) {
  dt.Rows.Add("Max Group of Hospitals");
  dt.Rows.Add("Fortis Group of Hospitals");
  dt.Rows.Add("Manipal Group of Hospitals");
  dt.Rows.Add("Appolo Group of Hospitals");
}

接下来我们需要订阅每个网格的 CellDoubleClick 事件来前后移动行。为了简化事情,不是编写代码将行从左向右移动,而是编写更多代码将行从右向左移动……我们编写了一种可以适应这两种移动的方法。

在这个方法中,我们需要知道哪个“Grid”是“源”网格,以便我们可以从中获取当前选定的单元格。从传入的网格中我们可以得到它的 DataSource DataTable 这样我们就可以删除选定的行。我们唯一需要的另一件事是将行添加到的目标网格数据源。这两项被传递到 MoveRow 方法中。这应该简化以任何一种方式移动行,并且可能如下所示......

private void MoveRow(DataGridView sourceGrid, DataTable destDT) {
  int sourceRowIndex = sourceGrid.CurrentRow.Index;
  if (sourceRowIndex >= 0 && !sourceGrid.Rows[sourceRowIndex].IsNewRow) {
    DataRowView selectedRow = (DataRowView)sourceGrid.Rows[sourceRowIndex].DataBoundItem;
    destDT.ImportRow(selectedRow.Row);
    ((DataTable)sourceGrid.DataSource).Rows.Remove(selectedRow.Row);
  }
}

上面的代码很简单……首先我们得到源网格的行索引CurrentRow。这是我们要移动到目标网格数据源的行。除了检查该行是否为网格 NewRow 之外,还进行了一些边界检查,在这种情况下我们不想移动该行。如果检查通过,那么我们用代码行从网格中抓取行...

DataRowView selectedRow = (DataRowView)sourceGrid.Rows[sourceRowIndex].DataBoundItem;

这将从网格 DataSource 中获取行。您可能会注意到,当代码将 sourceRowIndex 变量设置为…… int sourceRowIndex = sourceGrid.CurrentRow.Index; ……这是与 GRID ROWS 相关的行索引……您可能想从网格中获取行 DataSource 将 THAT 索引与诸如...

DataRowView selectedRow = sourceDT.Rows[sourceRowIndex]; 

这可能有效,也可能无效。如果网格未排序或过滤,则很有可能 one-to-one 对应于网格中的行索引和底层网格中的行索引 DataTable。但是,如果对网格进行排序或过滤,则此 one-to-one 对应关系将丢失。换句话说,网格行索引 3 处的行可能不一定位于基础数据源中的行索引 3 DataTable.

为了确保我们从网格数据源中获得“正确”的行,每个网格行都有一个 DataBoundItem 属性,这将为我们提供相应 DataRowDataTable 中。上面的代码显示了这一点,它使得从 table.

添加和删除该行变得更加容易

在我们获得源 DataTableDataRowView 之后,将 sourceDT table 中的行“导入”到目标 destDT table。然后从 sourceDT table 中删除该行。请注意,如果您尝试简单地将行从源“添加”到目标 table,则会出现错误。换句话说......而不是使用像......

这样的导入代码
 destDT.ImportRow(selectedRow.Row);

我们只是简单地添加了一行……

destDT.Rows.Add(selectedRow.Row);

该错误会提示您无法向已经属于另一个 table 的 table 添加行。即使您在尝试将行添加到目标 table 之前从源 table 中“删除”该行,您仍然会收到错误消息。我敢打赌该行仍然存在,但只是标记为删除。

幸运的是,使用 DataTables ImportRow 可以避免这种情况并帮助我们“复制”该行。因此,鉴于上面的 MoveRow 方法,它应该简化两个网格 CellDoubleClick 事件中的代码,并且可能看起来像...

private void availableFacilGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e) {
  MoveRow(availableFacilGrid, SelectedDT);
}

private void selectedFacilGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e) {
  MoveRow(selectedFacilGrid, AvailableDT);
}

我希望这对您有所帮助并且有意义。