2011-11-03 133 views
1

我有一个数据表,其具有四列,如如何将GridView中的行向上和向下移动?

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时,第二行应该成为第一行,第一行应该成为第二行。就像明智的,当我选择第二行并单击向下ImageButton时,第二行应该成为第三行,第三行应该成为第二行。像明智的我必须将所有行向上和向下移动

如何实现此目的? 我曾尝试向上和向下ImageButtons以下代码Click事件:

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列的源代码如下:

<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中向上和向下移动整行?请帮帮我。

+0

我想你应该正在寻找像设置'datatable1.DefaultView.Sort'属性根据你需要的列 – V4Vendetta

+0

@ V4Vendetta:我试过dtUp.DefaultView.Sort =“SeqNbr”;但移动SeqNbr值时没有正确分配。 – thevan

+0

你绑定了视图吗?底层数据类型是什么? – V4Vendetta

回答

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

应该工作?只要确保你不就顶行..;)

+0

是的。你是对的。我使用MileStoneID对其进行排序。但现在移动SeqNbr值时不能正确分配。上述编码的原因是什么? – thevan

+0

你不应该使用索引作为计数器。如果您总是按SeqNbr排序,您应该交换您希望交换的两行上的SeqNbr,然后刷新网格。 –

+0

出现同样的问题。一些行正确更改,但有时它错误地工作。 – thevan

0

试试这个

gvMileStone.DataSource = dtUp.DefaultView; 
+0

你绑定到DataTable(包含原始数据),而不是DefaultView(包含排序后的数据) – manuellt

+0

我也试过这个... – thevan

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 
2

而是由一个做基于gridview的一个更新的数据表中,你可以通过ToTable()方法应用于数据视图数据表的变化

如:

DataTable myData; 
myData = myData.DefaultView.ToTable(); 
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(); 
相关问题