Как перемещать строки в GridView вверх и вниз?

#c# #asp.net #visual-studio-2008 #gridview #datatable

#c# #asp.net #visual-studio-2008 #gridview #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, тогда вторая строка должна стать третьей строкой, а третья строка должна стать второй строкой. Как мудрый, я должен перемещать все строки вверх и вниз

Как этого добиться? Я попробовал следующую кодировку для события щелчка вверх и вниз 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 выглядит следующим образом:

 <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? пожалуйста, помогите мне.

Комментарии:

1. Я думаю, вам следует искать что-то вроде настройки datatable1.DefaultView.Sort свойства на основе нужного вам столбца

2. @V4Vendetta: Я попробовал DtUp.DefaultView. Sort = «SeqNbr»; Но при перемещении значения SeqNbr не задаются правильно.

3. Вы привязали представление? каковы базовые типы данных?

4. SeqNbr, MileStoneID — целое число, процент — десятичный, MileStoneName — строка

Ответ №1:

Попробуйте это.

вы выбрали индекс, сохраненный в переменной index.
теперь создайте один

 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:

Это желаемый ответ на мой вопрос.

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

Ответ №3:

Вместо того, чтобы обновлять datatable на основе gridview один за другим, вы можете просто применить изменения DataView к таблице данных методом ToTable()

Например:

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

Ответ №4:

Это только изменение одной ячейки, потому что вы только указываете ему изменить одну ячейку. Строка по-прежнему имеет тот же индекс. Чтобы строки менялись местами, вам нужно выполнить сортировку по правильному значению. (Моя интуиция подсказывает мне, что вы сортируете по 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;
        }
    }
  

должно работать? Просто убедитесь, что вы не в верхней строке .. 😉

Комментарии:

1. да. вы правы. Я сортирую его с помощью MileStoneID. Но теперь при перемещении значения SeqNbr не отображаются правильно. в чем может быть причина в приведенном выше коде?

2. Вы не должны возиться с использованием индекса в качестве счетчика. Если вы всегда сортируете по SeqNbr, вам следует поменять SeqNbr местами в двух строках, которые вы хотите поменять местами, а затем обновить сетку.

3. возникает та же проблема. некоторые строки изменяются правильно, но иногда это работает неправильно.

4. Тогда я думаю, что следующий шаг — перестать возиться с представлением данных и просто изменить источник и перенаправить / запросить.

Ответ №5:

Попробуйте это

 gvMileStone.DataSource = dtUp.DefaultView;
  

Комментарии:

1. вы привязываетесь к DataTable (который содержит исходные данные) вместо DefaultView (который содержит отсортированные данные)

Ответ №6:

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