Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Datatable "Copy" row to itself with ImportRow... Doubles Return?

Status
Not open for further replies.

tqeonline

MIS
Oct 5, 2009
304
US
I posted this in another place and was directed to this forum.

I have a datatable being stored as a Session and it databinds to a gridview. In this gridview I created a "Select" button and made its function to Duplicate the selected row.

ex. Duplicate row 1... then it adds that row to the datatable again.

Code:
    Protected Sub gvQueue_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvQueue.RowCommand
        If e.CommandName = "Select" Then
            'Retrieve the table from the session object.
            Dim dt = CType(Session("myDatatable"), DataTable)

            'Dims Index
            Dim index As Integer = Convert.ToInt32(e.CommandArgument)

            'Selects row to copy
            Dim row = dt.Rows(index)

            'Adds row to bottom of data table
            For Each dr As DataRow In dt.Rows
                dt.ImportRow(row)
            Next
            BindData()

            lblQueue.Text = gvQueue.Rows.Count
        End If
    End Sub

the BindData() is
Code:
    Private Sub BindData()
        gvQueue.DataSource = (CType(Session("myDatatable"), DataTable))
        gvQueue.DataBind()
    End Sub

This DOES duplicate the row to itself. However the issue now is this..

ex.
Before Duplication click
Row 1

After Duplication Click
Row 1
Row 1
Row 1

YES three rows instead of just two. I have tried everything I can think of for the past couple of hours and can't get it to just add 1 row.

Here is the page side code

Code:
            <asp:Panel ID="pnlTable" runat="server" Width="100%" ScrollBars="Both" Height="175px">
                <asp:UpdatePanel ID="UpdatePanel2" runat="server">
                <ContentTemplate>
                <asp:GridView ID="gvQueue" runat="server" Font-Size="Small" 
                    HorizontalAlign="Center" CellPadding="4" ForeColor="#333333" GridLines="None"
                    OnRowEditing="gvQueue_RowEditing"         
                    OnRowCancelingEdit="gvQueue_RowCancelingEdit" 
                    OnRowUpdating="gvQueue_RowUpdating"
                    OnPageIndexChanging="gvQueue_PageIndexChanging" 
                    AutoGenerateColumns="False" AllowSorting="True"
                    OnSorting="gvQueue_Sorting"
                    OnRowCommand="gvQueue_RowCommand">
                    <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
                    <Columns>
                        <asp:CommandField ShowEditButton="True" ButtonType="Button" />
                        <asp:CommandField SelectText="Duplicate" ShowSelectButton="True" ButtonType="Button" />
                        <asp:CommandField ShowDeleteButton="True" ButtonType="Button" />
                        ***I REMOVED THE REST OF THE COLUMNS FOR CONVENIENCE***                    </Columns>
                    
                    <EditRowStyle BackColor="#999999" HorizontalAlign="Center" Wrap="False" />
                    <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White"/>
                    <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" Wrap="False" />
                    <RowStyle BackColor="#F7F6F3" ForeColor="#333333" HorizontalAlign="Center" Wrap="False" />
                    <SortedAscendingCellStyle BackColor="#E9E7E2" Wrap="False" />
                    <SortedAscendingHeaderStyle BackColor="#506C8C" Wrap="False" />
                    <SortedDescendingCellStyle BackColor="#FFFDF8" Wrap="False" />
                    <SortedDescendingHeaderStyle BackColor="#6F8DAE" Wrap="False" />
                </asp:GridView>
                </ContentTemplate>
                </asp:UpdatePanel>
            </asp:Panel>

If you put an updatepanel within a panel it allows you to maintain the scrolling position within a gridview when it performs a "postback
 
I assume you are using VS web server cassinni for development. I have heard of cassinni firing page events multiple times. try using IIS and see if the problem continues.
If you put an updatepanel within a panel it allows you to maintain the scrolling position within a gridview when it performs a "postback"
this has nothing to do with it. an update panel just wraps a full postback within an ajax call.

Jason Meckley
Programmer

faq855-7190
faq732-7259
 
the next step is to remove the update panel and see if the bug still continues. I should, but it's a good idea to rule it out. once the problem is fixed you can add the update panel.

it could be the event is wired up twice, or request is processed twice. use the debugger to break into the gvQueue_RowCommand handler and step through the code.

Jason Meckley
Programmer

faq855-7190
faq732-7259
 
So it is going through the RowCommand twice for some reason.

SO I put a label on the page and set it to 0.

Then modified my code as such:
Code:
    Protected Sub gvQueue_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvQueue.RowCommand
        If e.CommandName = "Select" And lblDuplicate.Text = 0 Then
            'Retrieve the table from the session object.
            Dim dt = CType(Session("myDatatable"), DataTable)

            'Dims Index
            Dim index As Integer = Convert.ToInt32(e.CommandArgument)

            'Selects row to copy
            Dim row = dt.Rows(index)

            'Adds row
            dt.ImportRow(row)

            BindData()

            lblQueue.Text = gvQueue.Rows.Count
            lblDuplicate.Text = 1
        ElseIf lblDuplicate.Text = 1 Then
            lblDuplicate.Text = 0
        End If
    End Sub

And now it works. It basically prevents it from going twice.
 
I would find out why it's executing twice rather than hack the code.

Jason Meckley
Programmer

faq855-7190
faq732-7259
 
*Temp Fix* - i'm working on it.

I'll post when I figure it out.
 
do you have code like this?
Code:
protected void Page_Load(object sender, EventArgs e)
{
   if(IsPostBack) return;

   Grid.DataSource = data;
   DataBind();
}
if not, is may explain why the event is firing twice. the other place to look is BindData(). what's happening there?

Jason Meckley
Programmer

faq855-7190
faq732-7259
 
now for the VB version:

Code:
    Private Sub BindData()
            gvQueue.DataSource = (CType(Session("myDatatable"), DataTable))
            gvQueue.DataBind()
    End Sub

If i change it to this:
Code:
    Private Sub BindData()
        If IsPostBack = False Then
            gvQueue.DataSource = (CType(Session("myDatatable"), DataTable))
            gvQueue.DataBind()
        End If
    End Sub
Nothing gets done. Never enters the loop

If i make it = True then
Code:
If IsPostBack = True Then
It still has the double issue.
 
If i remove / comment out the UpdatePanel as such

Code:
            <asp:Panel ID="pnlTable" runat="server" Width="100%" ScrollBars="Both" Height="150px">
<%--                <asp:UpdatePanel ID=&quot;UpdatePanel2&quot; runat=&quot;server&quot;>
                <ContentTemplate>--%>
                <asp:GridView ID="gvQueue" runat="server" Font-Size="Small" 
                    HorizontalAlign="Center" CellPadding="4" ForeColor="#333333" GridLines="None"
                    OnRowEditing="gvQueue_RowEditing"         
                    OnRowCancelingEdit="gvQueue_RowCancelingEdit" 
                    OnRowUpdating="gvQueue_RowUpdating"
                    OnPageIndexChanging="gvQueue_PageIndexChanging" 
                    AutoGenerateColumns="False" AllowSorting="True"
                    OnSorting="gvQueue_Sorting"
                    OnRowCommand="gvQueue_RowCommand">
                    <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
                    <Columns>
                        <asp:CommandField ShowEditButton="True" ButtonType="Button" />
                        <asp:CommandField SelectText="Duplicate" ShowSelectButton="True" 
                            ButtonType="Button" CausesValidation="False" InsertVisible="False" 
                            ShowCancelButton="False" />
                        <asp:CommandField ShowDeleteButton="True" ButtonType="Button" />
                        ***COLUMNS REMOVED FOR SPACING***
                    </Columns>
                    
                    <EditRowStyle BackColor="#999999" HorizontalAlign="Center" Wrap="False" />
                    <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White"/>
                    <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" Wrap="False" />
                    <RowStyle BackColor="#F7F6F3" ForeColor="#333333" HorizontalAlign="Center" Wrap="False" />
                    <SortedAscendingCellStyle BackColor="#E9E7E2" Wrap="False" />
                    <SortedAscendingHeaderStyle BackColor="#506C8C" Wrap="False" />
                    <SortedDescendingCellStyle BackColor="#FFFDF8" Wrap="False" />
                    <SortedDescendingHeaderStyle BackColor="#6F8DAE" Wrap="False" />
                    <sortedascendingcellstyle backcolor="#E9E7E2" wrap="False" />
                    <sortedascendingheaderstyle backcolor="#506C8C" wrap="False" />
                    <sorteddescendingcellstyle backcolor="#FFFDF8" wrap="False" />
                    <sorteddescendingheaderstyle backcolor="#6F8DAE" wrap="False" />
                </asp:GridView>
<%--                </ContentTemplate>
                </asp:UpdatePanel>--%>
            </asp:Panel>

And I add a row via the "Add" button it never display the gridview. The lbl that I have displaying the number of rows increases. but the gridview never displays
 
I removed the panel and the update panel and it still occurs.
 
I can't figure it out and have to move to a different part of the page for a timeline i have to meet.

I changed it to this though:
Code:
    Protected Sub gvQueue_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvQueue.RowCommand
        'This allows you to enter a row right after the selected row for comparison. 
        'I have to use the lblduplicate because it performs a double postback and enters the entry twice instead of just once
        If e.CommandName = "Select" And lblDuplicate.Text = 0 Then
            Dim row As DataRow
            Dim dt = CType(Session("myDatatable"), DataTable)
            Dim objDataTable As New DataTable
            With objDataTable.Columns
                'Creates the columns
                .Add("COP", GetType(String))
                .Add("MDN Length", GetType(String))
                .Add("Cell Number", GetType(String))
                .Add("Area Code", GetType(String))
                .Add("Children", GetType(String))
                .Add("Active", GetType(String))
                .Add("Phone Make", GetType(String))
                .Add("Phone Model", GetType(String))
                .Add("Business Name", GetType(String))
                .Add("Last Name", GetType(String))
                .Add("First Name", GetType(String))
                .Add("Address 1", GetType(String))
                .Add("Address 2", GetType(String))
                .Add("City", GetType(String))
                .Add("State", GetType(String))
                .Add("Zip", GetType(String))
                .Add("Country ID", GetType(String))
                .Add("ESN", GetType(String))
                .Add("ESN Change Date", GetType(String))
                .Add("Enrollment Date", GetType(String))
                .Add("End Enrollment Date", GetType(String))
                .Add("Market Code", GetType(String))
                .Add("Feature Code", GetType(String))
                .Add("Account Number", GetType(String))
                .Add("Account Type", GetType(String))
                .Add("Dealer Code", GetType(String))
                .Add("Purchase Dealer Code", GetType(String))
            End With

            'Dims Index
            Dim index As Integer = Convert.ToInt32(e.CommandArgument)

            'Adds all the rows upto the index
            For x = 0 To index
                row = dt.Rows(x)
                objDataTable.ImportRow(row)
            Next

            'Adds row after index
            row = dt.Rows(index)
            objDataTable.ImportRow(row)

            'Adds all the rows after the index
            For y = index + 1 To gvQueue.Rows.Count - 1
                row = dt.Rows(y)
                objDataTable.ImportRow(row)
            Next

            Session("myDatatable") = objDataTable
            BindData()

            lblQueue.Text = gvQueue.Rows.Count
            lblDuplicate.Text = 1
        ElseIf lblDuplicate.Text = 1 Then
            lblDuplicate.Text = 0
        End If
    End Sub

What this allows is me to enter the row right after the current selected item. I do this so that the duplicated row is right next to the current one. Because if they are at row 750 and duplicate it down to row 1501 it's not that convenient.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top