简体   繁体   中英

How to move the rows in the GridView Up and Down?

I have one DataTable which has four columns such as

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

I bind this datatable with one GridView. Now I have two ImageButtons "imgbtnUp" and "imgbtnDown" which shows Up and Down Arrow Image.

When I select the second row of the GridView and Clicks the Up ImageButton, then the second row should become the first row and the first row should become the second row. Like wise when I select the second row and clicks the Down ImageButton, then the second row should become the third row and third row should become the second row. Like wise I have to move the all the rows Up and Down

How to achieve this? I have tried the following coding for the Up and Down ImageButtons Click Event:

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;
        }
 }

and My GridView Column's source code is as follows:

<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>                                    

At first, some rows are moving correctly, but after two or three click events its not working. How to move the Entire row Up and Down in the GridView? please help me.

Try this.

you have selected index stored in index variable.
now create one

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 

Instead of doing updating datatable based on gridview one by one, you can just apply the changes of DataView to data table by ToTable() method

Eg:

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

This is the desired answer for my question.

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;
   }
}

It's only changing a single cell because you are only telling it to change a single cell. The row still has the same index. To make the rows change places, you need to sort on the correct value. (My gut is telling me that you are sorting on MileStoneID and not on SeqNbr?)

the following is for the up button:

   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;
        }
    }

should work? Just make sure you are not on the top row.. ;)

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();

试试这个

gvMileStone.DataSource = dtUp.DefaultView;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM