유용한 정보

[C#] DataGridView 자동 행 번호 생성하는 방법(예제)

DevReff 2025. 5. 5. 11:44
728x90
728x90
SMALL

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CjControls
{
    public partial class CjDataGridView : DataGridView
    {
        #region Attributes
        /// <summary>
        /// 행번호를 자동으로 생성할지 여부 (default=false). RowHeadersVisible=true일 때 사용 가능함
        /// </summary>
        private bool m_bAutoRowIndex = false;
        [Browsable(true)]
        [Category("CjDataGridView")]
        [Description("행번호를 자동으로 생성할지 여부. RowHeadersVisible=true일 때 사용 가능함")]
        [DefaultValue(false)]
        public bool IsAutoRowIndex
        {
            get { return m_bAutoRowIndex; }
            set
            {
                this.RowHeadersVisible = value;
                if (m_bAutoRowIndex != value) 
                {
                    m_bAutoRowIndex = value;
                    this.Update();
                }
            }
        }

        /// <summary>
        /// 수평 스크롤바를 제거하도록 마지막 컬럼의 폭을 자동 조정할지의 여부 (default=true)
        /// </summary>
        private bool m_bAutoRemoveHScrollbar = true;
        [Browsable(true)]
        [Category("CjDataGridView")]
        [Description("수평 스크롤바를 제거하도록 마지막 컬럼의 폭을 자동 조정할지의 여부")]
        [DefaultValue(true)]
        public bool IsAutoRemoveHScrollbar
        {
            get { return m_bAutoRemoveHScrollbar; }
            set
            {
                m_bAutoRemoveHScrollbar = value; 
            }
        }

        /// <summary>
        /// 자동으로 생성되는 행의 시작번호 (default=1)
        /// </summary>
        private int m_nAutoIndexStartNo = 1;
        [Browsable(true)]
        [Category("CjDataGridView")]
        [Description("자동으로 생성되는 행의 시작번호")]
        [DefaultValue(1)]
        public int AutoIndexStartNo
        {
            get { return m_nAutoIndexStartNo; }
            set
            {
                if (value < 0)
                    return;
                m_nAutoIndexStartNo = value;
            }
        }

        [Browsable(false)]
        [Category("CjDataGridView")]
        [Description("바인딩 데이터테이블")]
        [DefaultValue(null)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public System.Data.DataTable BindingToTable
        {
            get 
            { 
                if (this.Columns.Count > 0)
                {
                    System.Data.DataTable dt = new System.Data.DataTable();

                    var cols = from DataGridViewColumn v in this.Columns orderby v.Index select v;
                    foreach (DataGridViewColumn v in cols)
                    {
                        System.Data.DataColumn c = dt.Columns.Add(v.Name, v.ValueType);
                        c.Caption = v.HeaderText;
                    }

                    var rows = from DataGridViewRow v in this.Rows orderby v.Index select v;
                    foreach (DataGridViewRow v in rows)
                    {
                        object[] dr = new object[this.Columns.Count];
                        for (int c = 0; c < this.Columns.Count; ++c)
                        {
                            dr[c] = this.Rows[v.Index].Cells[c].Value;
                        }
                        dt.Rows.Add(dr);
                    }

                    return dt;
                }
                else
                    return null;
            }
        }
       
        [Browsable(false)]
        [Category("CjDataGridView")]
        [Description("바인딩 데이터셋")]
        [DefaultValue(null)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public System.Data.DataSet BindingToSet
        {
            get
            {
                if (this.Columns.Count > 0)
                {
                    System.Data.DataSet ds = new System.Data.DataSet();
                    System.Data.DataTable dt = new System.Data.DataTable();

                    var cols = from DataGridViewColumn v in this.Columns orderby v.Index select v;
                    if (cols.Count() > 0)
                    {
                        foreach (DataGridViewColumn v in cols)
                        {
                            dt.Columns.Add(v.Name, v.ValueType);
                        }
                    }

                    var rows = from DataGridViewRow v in this.Rows orderby v.Index select v;
                    if (rows.Count() > 0)
                    {
                        foreach (DataGridViewRow v in rows)
                        {
                            object[] dr = new object[this.Columns.Count];
                            for (int c = 0; c < this.Columns.Count; ++c)
                                dr[c] = this.Rows[v.Index].Cells[c].Value;
                            dt.Rows.Add(dr);
                        }
                    }

                    ds.Tables.Add(dt);

                    return ds;
                }
                else
                    return null;
            }
        }

        [Browsable(false)]
        [Category("CjDataGridView")]
        [Description("바인딩 리스트")]
        [DefaultValue(null)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public BindingList<object> BindingToList
        {
            get
            {
                if (this.Columns.Count > 0 && this.Rows.Count > 0)
                {
                    BindingList<object> list = new BindingList<object>();
                    object[,] objects = new object[this.Rows.Count, this.Columns.Count];

                    var cols = (from DataGridViewColumn v in this.Columns orderby v.Index select v).ToList();
                    if (cols.Count() > 0)
                    {
                        for (int c = 0; c < this.Columns.Count; ++c)
                        {
                            objects[0, c] = cols[c].Name;
                        }
                    }

                    var rows = (from DataGridViewRow v in this.Rows orderby v.Index select v).ToList();
                    if (rows.Count() > 0)
                    {
                        for (int r = 0; r < this.Rows.Count; ++r)
                        {
                            for (int c = 0; c < this.Columns.Count; ++c)
                                objects[r, c] = rows[r].Cells[c].Value;
                        }
                    }

                    list.Add(objects);

                    return list;
                }
                else
                    return null;
            }
        }

        /// <summary>
        /// 칼럼별 수평 출력 방식
        /// </summary>
        private DataGridViewContentAlignment[] m_lstColumnAligns = null;
        [Browsable(true)]
        [Category("CjDataGridView")]
        [Description("칼럼별 수평 출력 방식")]
        [DefaultValue(null)]
        public DataGridViewContentAlignment[] ColumnAligns
        {
            get { return m_lstColumnAligns; }
            set
            {
                if (this.m_lstColumnAligns != null)
                {
                    m_lstColumnAligns.Initialize();
                    m_lstColumnAligns = null;
                }
                m_lstColumnAligns = value;
                Refresh();
            }
        }
        #endregion

        #region 생성자
        /// <summary>
        /// 생성자
        /// </summary>
        public CjDataGridView()
            : base()
        {
            InitializeComponent();
        }

#if _REMOVE_GGAMBBAK
        /// <summary>
        /// 화면에 표시될 때 생기는 화면 깜빡임 방지
        /// </summary>
        protected override CreateParams CreateParams
        {
            get
            {
                var cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }
#endif
        #endregion

        #region 컨트롤 이벤트 처리
        /// <summary>
        /// 마우스 다운했을 때
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            //Debug.WriteLine($"OnMouseDown started: {e.Button}, {e.Location}");
            base.OnMouseDown(e);
        }

        /// <summary>
        /// 사용자가 행을 추가한 후
        /// </summary>
        /// <param name="e"></param>
        protected override void OnUserAddedRow(DataGridViewRowEventArgs e)
        {
            try
            {
                base.OnUserAddedRow(e);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 모든 셀 그리기가 발생한 후 행 수준 그리기를 수행하기 위해 발생하는 이벤트 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRowPostPaint(DataGridViewRowPostPaintEventArgs e)
        {
            try
            {
                if (IsAutoRowIndex) 
                    DGV_AutoRowIndex(this, e);
                else
                    base.OnRowPostPaint(e);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            finally
            {
                if (IsAutoRemoveHScrollbar)
                    AutoRemoveHScrollbar();
            }
        }
        #endregion

        #region 외부함수
        /// <summary>
        /// 컨트롤 초기화
        /// </summary>
        /// <param name="bindingData">로딩할 데이터 데이블</param>
        public void InitControl(DataTable bindingData = null, List<DataGridViewContentAlignment> lstColumnAligns = null)
        {
            Cursor.Current = Cursors.WaitCursor;

            try
            {
                this.AllowUserToAddRows = false;
                this.AllowUserToDeleteRows = false;
                this.AllowUserToOrderColumns = false;
                this.AllowUserToResizeColumns = true;
                this.AllowUserToResizeRows = false;
                this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
                this.ReadOnly = true;
                this.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
                this.RowHeadersVisible = IsAutoRowIndex;

                this.Columns.Clear();
                this.DataSource = null;

                if (lstColumnAligns != null)
                {
                    if (this.m_lstColumnAligns != null)
                    {
                        m_lstColumnAligns.Initialize();
                        m_lstColumnAligns = null;
                    }
                    this.m_lstColumnAligns = lstColumnAligns.ToArray();
                }

                if (bindingData != null && bindingData.Columns.Count > 0)
                {
                    int wi = (this.Width - (IsAutoRowIndex ? this.RowHeadersWidth : 0)) / bindingData.Columns.Count;

                    for (int i = 0; i < bindingData.Columns.Count; i++)
                    {
                        DataColumn col = bindingData.Columns[i];
                        int c = this.Columns.Add(col.ColumnName, col.Caption);
                        this.Columns[c].DataPropertyName = col.ColumnName;
                        this.Columns[c].Width = wi;

                        if (m_lstColumnAligns == null)
                            m_lstColumnAligns = new DataGridViewContentAlignment[bindingData.Columns.Count];
                        if (m_lstColumnAligns.Count() <= c)
                            m_lstColumnAligns.Append(this.Columns[c].DefaultCellStyle.Alignment);
                        else
                            this.Columns[c].DefaultCellStyle.Alignment = m_lstColumnAligns[c];
                    }

                    foreach (DataRow row in bindingData.Rows)
                    {
                        int r = this.Rows.Add();
                        for (int c = 0; c < bindingData.Columns.Count; c++)
                        {
                            this.Rows[r].Cells[c].Value = row[c] as string;
                        }
                    }

                    this.DataSource = bindingData;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        /// <summary>
        /// 수평 스크롤바를 제거하도록 마지막 컬럼의 폭을 자동 조정한다.
        /// </summary>
        public void AutoRemoveHScrollbar()
        {
            try
            {
                int lastColumnWidth = (this.Width - (IsAutoRowIndex ? this.RowHeadersWidth : 0))
                    - (from DataGridViewColumn v in this.Columns
                       where v.Index != (this.Columns.Count - 1)
                       select v.Width).Sum();
                if (this.Width < this.RowTemplate.Height * this.Rows.Count)
                {
                    this.Columns[this.Columns.Count - 1].Width = lastColumnWidth
                        - SystemInformation.VerticalScrollBarWidth
                        - SystemInformation.FrameBorderSize.Width;
                    this.Update();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

반응형


        /// <summary>
        /// DataGridView 의 RowHeader 에 일련번호 자동생성 
        /// </summary>
        /// <param name="sender">DataGridView 컨트롤</param>
        /// <param name="e">이벤트정보</param>
        /// <param name="startno">시작번호</param>
        /// <remarks>DataGridView의 RowPostPaint 이벤트에 사용함</remarks>
        public void DGV_AutoRowIndex(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            if (sender is DataGridView)
            {
                try
                {
                    DataGridView dgv = sender as DataGridView;
                    if (dgv != null && dgv.RowHeadersVisible && dgv.Rows.Count > 0 && e.RowIndex >= 0)
                    {
                        String rowIdx = (AutoIndexStartNo + e.RowIndex).ToString();
                        StringFormat centerFormat = new StringFormat()
                        {
                            Alignment = StringAlignment.Center,
                            LineAlignment = StringAlignment.Center
                        };

                        RectangleF headerBounds = new RectangleF(e.RowBounds.Left, e.RowBounds.Top, dgv.RowHeadersWidth, e.RowBounds.Height);
                        e.Graphics.DrawString(rowIdx, dgv.Font, SystemBrushes.ControlText, headerBounds, centerFormat);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                }
            }
        }

        /// <summary>
        /// 칼럼별 출력 방식 설정하기
        /// </summary>
        /// <param name="formats">칼럼별 출력 방식</param>
        public void SetColumnAligns(List<DataGridViewContentAlignment> formats)
        {
            if (formats != null && formats.Count > 0)
            {
                if (m_lstColumnAligns != null)
                {
                    m_lstColumnAligns.Initialize(); 
                    m_lstColumnAligns = null ;
                }
                m_lstColumnAligns = formats.ToArray();
            }
        }

        /// <summary>
        /// 바인딩 리스트를 출력하기
        /// </summary>
        /// <param name="sb">저장할 문자열 목록</param>
        /// <param name="limit">한계 행 갯수 (0이면 무시, 0보다 클때만 적용됨)</param>
        /// <param name="bDebug">디버깅창에 출력만 할 것인지 여부</param>
        public void OutputBindingToList(out StringBuilder sb, int limit = 0, bool bDebug = true)
        {
            sb = new StringBuilder();

            if (BindingToList != null)
            {
                foreach (object[,] v in BindingToList)
                {
                    int nRow = v.GetLength(0);
                    int nCol = v.GetLength(1);

                    for (int r = 0; r < nRow; r++)
                    {
                        if (limit > 0 && r >= limit)
                            break;

                        string s = $"[{r + 1}] ";
                        for (int c = 0; c < nCol; c++)
                            s += $"{v[r, c].ToString()}, ";

                        if (!bDebug)
                            sb.AppendLine(s);
                        Debug.WriteLine(s);
                    }
                }
            }
        }

        #endregion
    }
}

728x90
728x90
LIST