【问题标题】:changing the order of records in dataset更改数据集中记录的顺序
【发布时间】:2015-06-11 06:20:33
【问题描述】:

我正在尝试根据用户偏好对数据集中的记录进行排序。我添加了一个按钮(向上移动)将所选记录向上提升 1 行,这就是我到目前为止所做的:

private void btnMoveUp_Click(object sender, EventArgs e)
{
    int index = dataGridView1.CurrentRow.Index;
    if (index >= 1) 
    { 
        var temp = dsWinners.Tables[0].Rows[index];
        dsWinners.Tables[0].Rows[index].Delete();
        dsWinners.Tables[0].Rows.InsertAt(temp, index - 1);
        dsWinners.Tables[0].AcceptChanges();
        dataGridView1.DataSource = dsWinners.Tables[0];
    }
}

但我收到一条错误消息,提示“此行已属于此表。”在这一行:

dsWinners.Tables[0].Rows.InsertAt(temp, index - 1);

我知道我必须使用 ImportRow(temp) 而不是 InsertAt(temp, index - 1) 但问题是我不知道如何在正确的位置导入它。我已经看过THIS,但正如回答问题的人所说“它草率且半途而废。”

无论如何我可以克服这个问题吗?如果是,我该怎么做?

【问题讨论】:

  • 尝试在删除之后和插入之前调用 AcceptChanges 以及您已经拥有的一个
  • 另一种方法是在表中添加一个位置列(如果还没有),并在开头使用位置 (1 ... n) 对其进行初始化。按此列对视图进行排序。当用户想要更改位置时,您只需将单元格的值交换为两行并断言视图仍按此列排序。
  • @Adil 我添加了 AcceptChanges();删除后和插入后。它删除了该行,在其顶部添加了一个新行,但它是空的!!!可能是因为 temp 为空还是只是没有将其内容添加到新行?
  • @Markus 我没有它,因为该表没有从数据库中提取...它是从 excel 生成的表单和二维数组的组合。但是我可以添加该列并将其隐藏吗?比如我可以让可见的为假吗?
  • 我认为@Markus 方法更好。您是否尝试过在方法中交换 Delete 和 InsertAt 行并测试结果?

标签: c# winforms datagridview dataset


【解决方案1】:

您可以在包含该位置的表中添加一列,而不是删除该行并在另一个位置再次添加它。

您不会将 DataGridView 绑定到表本身,而是绑定到按 Position 列排序的 DataView。

在 DataGridView 中,您将添加除 Position 之外的所有列,以便不显示 Position。

当您向上或向下移动一行时,您将位置单元格的值分别与上一行或下一行交换。由于 DataView 是按位置排序的,因此移动会立即反映在 DataView 中。

以下控制台应用程序显示了基本步骤:

void Main()
{
    // Create a new DataTable
    DataTable tbl = GetData();
    // Add Position column and initialize it
    tbl.Columns.Add("Position", typeof(int));
    for(int i = 0; i < tbl.Rows.Count; i++) 
        tbl.Rows[i]["Position"] = i;
    PrintView("Original", tbl.DefaultView);

    // Create a view that is sorted by the Position column
    var view = new DataView(tbl);
    view.Sort = "Position";
    PrintView("Sorted", view); // No change as the rows are in original order anyway

    // Move a row
    SwapPositions(view, 0, 1); // Move first row down
    PrintView("Swapped", view);
}

private DataTable GetData()
{
    DataTable tbl = new DataTable();
    tbl.Columns.Add("Value", typeof(string));
    for(int i = 0; i < 3; i++)
        tbl.Rows.Add("Text " + i.ToString());
    return tbl;
}

private void PrintView(string header, DataView view)
{
    Console.WriteLine(header);
    foreach(DataRowView row in view)
        Console.WriteLine("{0}\t{1}", row["Position"], row["Value"]);
}

private void SwapPositions(DataView view, int rowIndex1, int rowIndex2)
{
    // Save rows as the change in the Position column is reflected immediately
    DataRowView row1 = view[rowIndex1];
    DataRowView row2 = view[rowIndex2];
    // Now swap positions
    var saveValue = row1["Position"];
    row1["Position"] = row2["Position"];
    row2["Position"] = saveValue;
    view.Table.AcceptChanges();
}

输出是:

Original
0  Text 0
1  Text 1
2  Text 2
Sorted
0  Text 0
1  Text 1
2  Text 2
Swapped
0  Text 1
1  Text 0
2  Text 2

【讨论】:

    【解决方案2】:

    试试下面的东西:

    var temp = dsWinners.Tables[0].Rows[index];         \\getting row
    var newrow = dsWinners.Tables[0].NewRow();     \\ creating new row to insert
    newrow.ItemArray = temp.ItemArray;            \\ copying data from old to new row
    dsWinners.Tables[0].Rows[index].Delete(); \\deleting old row.
     dsWinners.Tables[0].Rows.InsertAt(newrow, index - 1); \\ adding new row.
    

    【讨论】:

    • 这段代码有问题。它只会向上移动 1 行。
    • 从您的代码中,我认为您也想做同样的事情,但是如果所有行都需要移动,那么 Markus 的解决方案是一个好方法.. 但稍作修改,而不是在行处理level 为数据表设置过滤器表达式将有效地完成任务,stackoverflow.com/questions/9107916/… 根据添加的列进行排序。
    【解决方案3】:

    您可以再尝试一件事。尝试替换代码

    var temp = dsWinners.Tables[0].Rows[index]; 
    

    带有以下内容::

    var temp = dsWinners.Tables[0].NewRow();    
    temp.ItemArray = dsWinners.Tables[0].ItemArray;
    

    这是创建一个新行并将其移动到给定位置,而不是移动现有位置。

    【讨论】:

    • 它仍然返回空白
    【解决方案4】:

    这是为了将最后一个索引表移动到数据集中的第一个索引:

            DataSet dsIndexchange = new DataSet();
            DataTable dtdummysummary = new DataTable();
            dtdummysummary = dsAssetInterval.Tables[dsAssetInterval.Tables.Count-1];
    
            dsAssetInterval.Tables.RemoveAt(dsAssetInterval.Tables.Count-1);
            dsIndexchange.Tables.Add(dtdummysummary);
            for (int i = 0; i < dsAssetInterval.Tables.Count; i++)
            {
                dsIndexchange.Tables.Add(dsAssetInterval.Tables[i].Copy());
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      • 1970-01-01
      相关资源
      最近更新 更多