65.9K
CodeProject is changing. Read more.
Home

A method to move rows within a DataTable

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.86/5 (6 votes)

Jan 13, 2012

CPOL
viewsIcon

16967

Nice solution agent154, I'd just suggest to implement it as extension methods for data row: (and I don't liked your "error reporting" with the '0' Value - because '0' could be a valid index). But I have to say, even if you don't have a database behind the datatable you can use sorting (LINQ,...

Nice solution agent154, I'd just suggest to implement it as extension methods for data row: (and I don't liked your "error reporting" with the '0' Value - because '0' could be a valid index). But I have to say, even if you don't have a database behind the datatable you can use sorting (LINQ, ...) to put the rows in the correct sequence. But, for your example you have given in the comments (recipe) I would add an "ingredient number" to the datamodel (xml) and sort it while filling the datatable (or if files are deserialized as they are, while serializing)
using System;
using System.Data;
using System.Text;

namespace MoveRow
{
    static class ExtensionMethods
    {
        const int m_iNO_MOVE_OCCURED = -1; // number to indicate error

        public static int MoveRowUp(this DataRow row)
        {
            DataTable dtParent = row.Table;
            int iOldRowIndex = dtParent.Rows.IndexOf(row);

            DataRow newRow = dtParent.NewRow();
            newRow.ItemArray = row.ItemArray;

            if (iOldRowIndex < dtParent.Rows.Count)
            {
                dtParent.Rows.Remove(row);
                dtParent.Rows.InsertAt(newRow, iOldRowIndex + 1);
                return dtParent.Rows.IndexOf(newRow);
            }

            return m_iNO_MOVE_OCCURED;
        }

        public static int MoveRowDown(this DataRow row)
        {
            DataTable dtParent = row.Table;
            int iOldRowIndex = dtParent.Rows.IndexOf(row);

            DataRow newRow = dtParent.NewRow();
            newRow.ItemArray = row.ItemArray;

            if (iOldRowIndex > 0)
            {
                dtParent.Rows.Remove(row);
                dtParent.Rows.InsertAt(newRow, iOldRowIndex - 1);
                return dtParent.Rows.IndexOf(newRow);
            }

            return m_iNO_MOVE_OCCURED;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Value", typeof(int));
            dt.Rows.Add("Row1", 1);
            dt.Rows.Add("Row2", 2);
            dt.Rows.Add("Row3", 3);
            dt.Rows.Add("Row4", 4);
            dt.Rows.Add("Row5", 5);

            Console.WriteLine("initial");
            WriteRows(dt);
            Console.WriteLine();

            DataRow row = dt.Rows[3]; // take any row for testing the move functions
            int iResult = row.MoveRowDown();
            Console.WriteLine("After move down");
            WriteRows(dt);
            Console.WriteLine();

            Console.ReadKey();
        }

        static void WriteRows(DataTable dt)
        {
            // Header
            StringBuilder sbHeader = new StringBuilder();
            foreach (DataColumn column in dt.Columns)
            {
                sbHeader.Append(String.Format("{0}\t\t", column.ColumnName));
            }
            Console.WriteLine(sbHeader.ToString());
            Console.WriteLine();

            // Rows
            foreach (DataRow row in dt.Rows)
            {
                StringBuilder sbLine = new StringBuilder();
                foreach (DataColumn column in dt.Columns)
                {
                    sbLine.Append(String.Format("{0}\t\t", row[column]));
                }
                Console.WriteLine(sbLine.ToString());
            }
        }
    }
}