如何在GridView中向上和向下移动行?

时间:2011-11-03 11:50:38

标签: c# asp.net visual-studio-2008 gridview datatable

我有一个DataTable有四列,如

    MileStoneID      MileStoneName       Percentage     SeqNbr
   -------------    ---------------     ------------    ------
        1               M-One               25             1
        2               M-Two               30             2
        3               M-Three             50             3
        10              M-Four              20             4

我将这个数据表绑定到一个GridView。现在我有两个ImageButtons“imgbtnUp”和“imgbtnDown”,它显示了向上和向下箭头图像。

当我选择GridView的第二行并单击Up ImageButton时,第二行应成为第一行,第一行应成为第二行。当我选择第二行并单击Down ImageButton时,第二行应该成为第三行,第三行应该成为第二行。同样明智的我必须向上和向下移动所有行

如何实现这一目标? 我已经尝试了以下编码的Up和Down ImageButtons点击事件:

protected void imgbtnUp_Click(object sender, ImageClickEventArgs e)
{        
    if (gvMileStone.Rows.Count > 0)
    {
            int index = gvMileStone.SelectedIndex;
            if (index == 0)
            {
                ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel), Guid.NewGuid().ToString(), "window.alert('You cannot move the record up!')", true);
                return;
            }
            else
            {
                DataTable dtUp = (DataTable)ViewState["Template"];//dtUp is the DataTable I mentioned above
                int value = Convert.ToInt32(dtUp.Rows[index]["SeqNbr"].ToString());
                dtUp.Rows[index]["SeqNbr"] = Convert.ToInt32(index + 1) - 1;
                dtUp.Rows[index - 1]["SeqNbr"] = value;  
                dtUp.DefaultView.Sort = "SeqNbr";                   
                dtUp.AcceptChanges();
                gvMileStone.DataSource = dtUp;
                gvMileStone.DataBind();
                ViewState["Template"] = dtUp;
            }
   }
   else
   {
            ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel), Guid.NewGuid().ToString(), "window.alert('There is no rows to move!')", true);
            return;
    }
}

protected void imgbtnDown_Click(object sender, ImageClickEventArgs e)
{        
        if (gvMileStone.Rows.Count > 0)
        {
            DataTable dtDown = (DataTable)ViewState["Template"];
            int index = gvMileStone.SelectedIndex;
            if (index + 1 == dtDown.Rows.Count)
            {
                ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel), Guid.NewGuid().ToString(), "window.alert('You cannot move the record down!')", true);
                return;
            }
            else
            {
                int value = Convert.ToInt32(dtDown.Rows[index]["MileStoneID"].ToString());
                dtDown.Rows[index]["MileStoneID"] = Convert.ToInt32(dtDown.Rows[index]["MileStoneID"].ToString()) + 1;
                dtDown.Rows[index + 1]["MileStoneID"] = value;
                dtDown.AcceptChanges();
                dtDown.DefaultView.Sort = "MileStoneID";
                dtDown.AcceptChanges();
                FillGrid(dtDown, gvMileStone);
                ViewState["Template"] = dtDown;
            }
        }
        else
        {
            ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel), Guid.NewGuid().ToString(), "window.alert('There is no rows to move!')", true);
            return;
        }
 }

和我的GridView Column的源代码如下:

<Columns>
    <asp:TemplateField Visible="false">
        <ItemTemplate>
           <asp:Label ID="lblMileStoneID" runat="server" Text='<%# Bind("MileStoneID") %>'></asp:Label>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:BoundField DataField="MileStoneName" HeaderText="MileStone Name" SortExpression="MileStoneName" ItemStyle-Width="130px" />
    <asp:TemplateField HeaderText="Percentage">
        <ItemTemplate>
           <asp:TextBox ID="txtPercentage" runat="server" Text='<%# Bind("Percentage") %>' Width="50px" onkeypress="return DecimalValidate(event);"></asp:TextBox>
        </ItemTemplate>
        <ItemStyle Width="100px" />
        <ControlStyle Width="100px" />
    </asp:TemplateField>
    <asp:TemplateField Visible="false">
        <ItemTemplate>
           <asp:Label ID="lblSeqNbr" runat="server" Text='<%# Bind("SeqNbr") %>'></asp:Label>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField Visible="false">
    <ItemTemplate>
       <asp:LinkButton ID="lnkSelect" runat="server" CommandName="select" Text="select" />
    </ItemTemplate>
    </asp:TemplateField>
</Columns>                                    

首先,某些行正确移动,但在两到三次点击事件后,它无法正常工作。如何在GridView中上下移动整行?请帮帮我。

6 个答案:

答案 0 :(得分:4)

试试这个。

您已选择存储在索引变量中的索引 现在创建一个

DataRow row;
row = dtUp.row[index];
dtUp.Rows.RemoveAt[index];
dtUp.Rows.InsertAt[dr,index+1] //for down
dtUp.Rows.InsertAt[dr,index-1] //for up 

答案 1 :(得分:2)

这是我的问题的理想答案。

protected void imgbtnUp_Click(object sender, ImageClickEventArgs e)
{   
    DataTable dt = new DataTable();
    DataTable dtnew = new DataTable();    
    if (gvMileStone.Rows.Count > 0)
    {
        int index = gvMileStone.SelectedIndex;
        if (index == 0)
        {
            ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel), Guid.NewGuid().ToString(), "window.alert('You cannot move the record up!')", true);
            return;
        }
        else
        {
            dt = (DataTable)ViewState["Template"];//dt is the DataTable I mentioned above
            int value = Convert.ToInt32(dt.Rows[index]["SeqNbr"].ToString());
            dt.Rows[index]["SeqNbr"] = Convert.ToInt32(index) - 1;
            dt.Rows[index - 1]["SeqNbr"] = value;// Convert.ToInt32(index);
            dt.DefaultView.Sort = "SeqNbr";
            dt.AcceptChanges();
            dtnew = dt.Copy();
            gvMileStone.DataSource = dt;
            gvMileStone.DataBind();
            dt.AcceptChanges();
            for (int i = 0; i <= gvMileStone.Rows.Count - 1; i++)
            {
                dtnew.Rows[i]["MileStoneID"] = Convert.ToInt32(((Label)gvMileStone.Rows[i].FindControl("lblMileStoneID")).Text);
                dtnew.Rows[i]["MileStoneName"] = gvMileStone.Rows[i].Cells[1].Text;
                dtnew.Rows[i]["Percentage"] = Convert.ToDecimal(((TextBox)gvMileStone.Rows[i].FindControl("txtPercentage")).Text);
                dtnew.Rows[i]["SeqNbr"] = Convert.ToInt32(((Label)gvMileStone.Rows[i].FindControl("lblSeqNbr")).Text);
            }
            ViewState["Template"] = dtnew;
        }
   }
   else
   {
        ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel), Guid.NewGuid().ToString(), "window.alert('There is no rows to move!')", true);
        return;
   }
}

答案 2 :(得分:2)

您可以通过ToTable()方法将DataView的更改应用于数据表,而不是逐个更新基于gridview的数据表

例如:

DataTable myData;
myData = myData.DefaultView.ToTable();

答案 3 :(得分:1)

它只会更改单个单元格,因为您只是告诉它更改单个单元格。该行仍具有相同的索引。要使行更改位置,您需要对正确的值进行排序。 (我的直觉告诉我你在MileStoneID上排序,而不是在SeqNbr上排序?)

以下是关闭按钮:

   if (gvMileStone.Rows.Count > 0)
    {
        int index = gvMileStone.SelectedIndex;
        if (index != 0)
        {
            DataTable dtUp = (DataTable)ViewState["Template"];
            int value = Convert.ToInt32(dtUp.Rows[index]["SeqNbr"].ToString());
            dtUp.Rows[index]["SeqNbr"] = value - 1;
            dtUp.Rows[index - 1]["SeqNbr"] = value;
            dtUp.DefaultView.Sort = "SeqNbr";                   
            dtUp.AcceptChanges();
            gvMileStone.DataSource = dtUp;
            gvMileStone.DataBind();
            ViewState["Template"] = dtUp;
        }
    }

应该有用吗?只要确保你不在最上面..;)

答案 4 :(得分:0)

试试这个

gvMileStone.DataSource = dtUp.DefaultView;

答案 5 :(得分:0)

DataRow dr = dt.Rows[selectedIndex];
ArrayList drList = new ArrayList();
for (int i = 0; i < dt.Columns.Count; i++)
{
    drList.Add(dr[i]);
}

dt.Rows[selectedIndex].Delete();
dt.AcceptChanges();

DataRow drNew = dt.NewRow();

for (int i = 0; i < drList.Count; i++)
{
    drNew[i] = drList[i];
}

drList = null;

dt.Rows.InsertAt(drNew, (selectedIndex));
dt.AcceptChanges();