블로그 이미지
따시쿵

calendar

1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Notice

2015. 5. 7. 11:22 C# with ListView

프로그램 설명


페이지 나누기가 있는 ListView 예제입니다.

기본적인 아이디어는 Listview Paging in C# 에 있는 자료를 가져다가 사용했으며, 몇가지 성능을 위해서 수정한 부분이 있습니다.


수정한 부분


1. 데이타 쿼리는 폼이 로드될 시에 전체적으로 한번만 데이타베이스에서 가져오고 그 다음 페이지 이동시에는 처음 로드한 데이타셋에서 자료를 가져옵니다.


2. 하단에 있는 처음으로, 이전으로, 다음으로, 마지막으로 버튼 이벤트를 한 곳으로 모아서 처리했습니다.


3. 컬럼 이벤트를 주어서 sorting 기능도 추가했습니다. (ascending, descending)


실행 후



프로그램 작성 순서


1. 페이지 나누기 기본 알고리즘

        static void Main(string[] args)
        {
            int TotalRec, NRPP;
            double TotalPages = 0;
            String p;
            System.Console.WriteLine("Enter Total Records");
            TotalRec = Convert.ToInt32(System.Console.ReadLine());
            //Getting value to set number records are shown in the page. 
            System.Console.WriteLine("Enter No. of Records Per Page");
            NRPP = Convert.ToInt32(System.Console.ReadLine());
            //calculating Total Pages
            TotalPages = Math.Ceiling( Convert.ToDouble(TotalRec) / NRPP);

            System.Console.WriteLine("The Total Pages:{0}", TotalPages);
            //Creating Page Indexes
            int i, j;
            for (int k = 1; k <= TotalPages; k++)
            {
                System.Console.WriteLine("\n\n Page No:{0} \n", k);
                i = (k - 1) * NRPP;
                int start = i;
                int end = 0;
                j = k * NRPP;
                for (; i < j; i++)
                {
                    if (i >= TotalRec)
                    {
                        break;
                    }
                    System.Console.WriteLine("Record Index:{0}", i);
                    end = i;
                }
                System.Console.WriteLine("Records Showing From {0} to {1}", (start + 1), (end + 1));
                System.Console.WriteLine("*****End of Page***** \n");
                p = System.Console.ReadLine();
            }
        }


2. 전역 변수들

    public class LsvPageGlobVar
    {
        public static string ConStr;
        public static DataTable sqlDataTable = new DataTable();
        public static int TotalRec;         //Variable for getting Total Records of the Table
        public static int NRPP;             //Variable for Setting the Number of Recrods per listiview page
        public static int Page;             //List View Page for Navigate or move
        public static double TotalPages;    //Varibale for Counting Total Pages.
        public static int RecStart;         //Variable for Getting Every Page Starting Record Index
        public static int RecEnd;           //Variable for Getting Every Page End Record Index
    }


3. 페이지별로 데이타 가져오는 method

    public class LsvPageFunc
    {
        public static void FillLsvData(BindingList<contacts> sqlData, ListView lvList, int imageID)
        {
            lvList.Items.Clear();
            
            // total record count
            LsvPageGlobVar.TotalRec = sqlData.Count;

            // calculate total page count
            LsvPageGlobVar.TotalPages = Math.Ceiling(Convert.ToDouble(LsvPageGlobVar.TotalRec) / LsvPageGlobVar.NRPP);
         

            //for adding records to the listview from datatable
            int l, k;

            l = (LsvPageGlobVar.Page - 1) * LsvPageGlobVar.NRPP;
            k = ((LsvPageGlobVar.Page) * LsvPageGlobVar.NRPP);

            LsvPageGlobVar.RecStart = l + 1;
            if (k > LsvPageGlobVar.TotalRec)
            {
                LsvPageGlobVar.RecEnd = LsvPageGlobVar.TotalRec;
            }
            else
            {
                LsvPageGlobVar.RecEnd = k;
            }

            int index = 0;
            for (; l < k; l++)
            {
                if (l >= LsvPageGlobVar.TotalRec)
                {
                    break;
                }

                // Not display image
                //ListViewItem item = new ListViewItem();
                //item.Text = sqlData[l].Idx.ToString();
                //item.SubItems.Add(sqlData[l].Name);
                //item.SubItems.Add(sqlData[l].BirthInfo);
                //item.SubItems.Add(sqlData[l].ZipCode);
                //item.SubItems.Add(sqlData[l].Address);
                //item.SubItems.Add(sqlData[l].HomeTelephone);
                //item.SubItems.Add(sqlData[l].CompanyTelephone);
                //item.SubItems.Add(sqlData[l].Mobile);
                //item.SubItems.Add(sqlData[l].Company);
                //item.SubItems.Add(sqlData[l].RegDate);
                //lvList.Items.Add(item);

                // Display image
                lvList.Items.Add(sqlData[l].Idx.ToString(), imageID);
                lvList.Items[index].SubItems.Add(sqlData[l].Name);
                lvList.Items[index].SubItems.Add(sqlData[l].BirthInfo);
                lvList.Items[index].SubItems.Add(sqlData[l].ZipCode);
                lvList.Items[index].SubItems.Add(sqlData[l].Address);
                lvList.Items[index].SubItems.Add(sqlData[l].HomeTelephone);
                lvList.Items[index].SubItems.Add(sqlData[l].CompanyTelephone);
                lvList.Items[index].SubItems.Add(sqlData[l].Mobile);
                lvList.Items[index].SubItems.Add(sqlData[l].Company);
                lvList.Items[index].SubItems.Add(sqlData[l].RegDate);

                index++;
            }
        }
    }


4. 실제적으로 페이지별로 데이타 호출하는 방법

            Button button = (Button)sender;
            
            switch(button.Name)
            {
                case "btnFirst":
                    {
                        LsvPageGlobVar.Page = 1;
                        LsvPageFunc.FillLsvData(ContactList, lsvData, 0);
                        lblInfo.Text = "Record Shown: " + LsvPageGlobVar.RecStart + " to " + LsvPageGlobVar.RecEnd + "                      Page " + LsvPageGlobVar.Page + " of " + LsvPageGlobVar.TotalPages;

                        break;
                    }
                case "btnPrev":
                    {
                        if (LsvPageGlobVar.Page > 1)
                        {
                            LsvPageGlobVar.Page--;
                        }
                        LsvPageFunc.FillLsvData(ContactList, lsvData, 1);
                        lblInfo.Text = "Record Shown: " + LsvPageGlobVar.RecStart + " to " + LsvPageGlobVar.RecEnd + "                      Page " + LsvPageGlobVar.Page + " of " + LsvPageGlobVar.TotalPages;

                        break;
                    }
                case "btnNext":
                    {
                        if (LsvPageGlobVar.Page < LsvPageGlobVar.TotalPages)
                        {
                            LsvPageGlobVar.Page++;
                        }
                        LsvPageFunc.FillLsvData(ContactList, lsvData, 2);
                        lblInfo.Text = "Record Shown: " + LsvPageGlobVar.RecStart + " to " + LsvPageGlobVar.RecEnd + "                      Page " + LsvPageGlobVar.Page + " of " + LsvPageGlobVar.TotalPages;

                        break;
                    }
                case "btnLast":
                    {
                        LsvPageGlobVar.Page = Convert.ToInt32(LsvPageGlobVar.TotalPages);
                        LsvPageFunc.FillLsvData(ContactList, lsvData, 3);
                        lblInfo.Text = "Record Shown: " + LsvPageGlobVar.RecStart + " to " + LsvPageGlobVar.RecEnd + "                      Page " + LsvPageGlobVar.Page + " of " + LsvPageGlobVar.TotalPages;

                        break;
                    }
            }


소스 파일 :

ListViewExample5.zip


posted by 따시쿵
2015. 4. 30. 15:53 C# with ListView

프로그램 설명


ListView 은 sorting 기능을 items 에서 지원하므로, 수작업으로 sub-items 까지 sorting 하는 기능을 작성해야 합니다. 그래서 필수적인 IComparer 인터페이스를 이용해서 구현합니다. 


예제에 있는 sorting 타입은 3가지 타입으로 숫자, 날짜, 문자열로 나뉘어 구분합니다.


실행 후


프로그램 작성 순서


1. IComparer 에서 상속받은 ListViewComparer class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows.Forms;

namespace SortListViewColumn.lib
{
    // Compares two ListView items based on a selected column.
    public class ListViewComparer : System.Collections.IComparer
    {
        private int ColumnNumber;
        private SortOrder SortOrder;

        public ListViewComparer(int column_number, SortOrder sort_order)
        {
            ColumnNumber = column_number;
            SortOrder = sort_order;
        }

        // Compare two ListViewItems.
        public int Compare(object object_x, object object_y)
        {
            // Get the objects as ListViewItems.
            ListViewItem item_x = object_x as ListViewItem;
            ListViewItem item_y = object_y as ListViewItem;

            // Get the corresponding sub-item values.
            string string_x;
            if (item_x.SubItems.Count <= ColumnNumber)
            {
                string_x = "";
            }
            else
            {
                string_x = item_x.SubItems[ColumnNumber].Text;
            }

            string string_y;
            if (item_y.SubItems.Count <= ColumnNumber)
            {
                string_y = "";
            }
            else
            {
                string_y = item_y.SubItems[ColumnNumber].Text;
            }

            // Compare them.
            int result;
            double double_x, double_y;
            if (double.TryParse(string_x, out double_x) &&
                double.TryParse(string_y, out double_y))
            {
                // Treat as a number.
                result = double_x.CompareTo(double_y);
            }
            else
            {
                DateTime date_x, date_y;
                if (DateTime.TryParse(string_x, out date_x) &&
                    DateTime.TryParse(string_y, out date_y))
                {
                    // Treat as a date.
                    result = date_x.CompareTo(date_y);
                }
                else
                {
                    // Treat as a string.
                    result = string_x.CompareTo(string_y);
                }
            }

            // Return the correct result depending on whether
            // we're sorting ascending or descending.
            if (SortOrder == SortOrder.Ascending)
            {
                return result;
            }
            else
            {
                return -result;
            }
        }
    }
}


2. ColumnClick 이벤트 method

        private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            // Get the new sorting column.
            ColumnHeader new_sorting_column = listView1.Columns[e.Column];

            // Figure out the new sorting order.
            System.Windows.Forms.SortOrder sort_order;
            if (SortingColumn == null)
            {
                // New column. Sort ascending.
                sort_order = SortOrder.Ascending;
            }
            else
            {
                // See if this is the same column.
                if (new_sorting_column == SortingColumn)
                {
                    // Same column. Switch the sort order.
                    if (SortingColumn.Text.StartsWith("> "))
                    {
                        sort_order = SortOrder.Descending;
                    }
                    else
                    {
                        sort_order = SortOrder.Ascending;
                    }
                }
                else
                {
                    // New column. Sort ascending.
                    sort_order = SortOrder.Ascending;
                }

                // Remove the old sort indicator.
                SortingColumn.Text = SortingColumn.Text.Substring(2);
            }

            // Display the new sort order.
            SortingColumn = new_sorting_column;
            if (sort_order == SortOrder.Ascending)
            {
                SortingColumn.Text = "> " + SortingColumn.Text;
            }
            else
            {
                SortingColumn.Text = "< " + SortingColumn.Text;
            }

            // Create a comparer.
            listView1.ListViewItemSorter = new ListViewComparer(e.Column, sort_order);

            // Sort.
            listView1.Sort();

            // Display order column and sorting type
            toolStripStatusLabel1.Text = "Sorting : " + SortingColumn.Text;
        }


소스 파일 : 

ListViewExample2.zip

posted by 따시쿵
2015. 4. 28. 15:18 C# with ListView

프로그램 설명


ListView 를 이용한 데이타베이스 연산 예제입니다.


데이타베이스 테이블은 아래와 같습니다.


CREATE TABLE [dbo].[tbl_contacts](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Name] [varchar](50) NOT NULL,
	[BirthInfo] [char](8) NOT NULL,
	[ZipCode] [char](7) NOT NULL,
	[Address] [varchar](300) NOT NULL,
	[HomeTelephone] [varchar](50) NOT NULL,
	[CompanyTelephone] [varchar](50) NOT NULL,
	[Mobile] [varchar](50) NOT NULL,
	[Company] [varchar](50) NOT NULL,
	[RegDate] [smalldatetime] NOT NULL,
 CONSTRAINT [PK_contacts] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[tbl_contacts] ADD  DEFAULT ('') FOR [Name]
GO

ALTER TABLE [dbo].[tbl_contacts] ADD  DEFAULT ('') FOR [BirthInfo]
GO

ALTER TABLE [dbo].[tbl_contacts] ADD  DEFAULT ('') FOR [ZipCode]
GO

ALTER TABLE [dbo].[tbl_contacts] ADD  DEFAULT ('') FOR [Address]
GO

ALTER TABLE [dbo].[tbl_contacts] ADD  DEFAULT ('') FOR [HomeTelephone]
GO

ALTER TABLE [dbo].[tbl_contacts] ADD  DEFAULT ('') FOR [CompanyTelephone]
GO

ALTER TABLE [dbo].[tbl_contacts] ADD  DEFAULT ('') FOR [Mobile]
GO

ALTER TABLE [dbo].[tbl_contacts] ADD  DEFAULT ('') FOR [Company]
GO

ALTER TABLE [dbo].[tbl_contacts] ADD  DEFAULT (getdate()) FOR [RegDate]
GO


실행 후


프로그램 작성 순서


데이타베이스에서 ListView 에 데이타 보여주기


            SQLOperator sdo = new SQLOperator("SampleDBConnectionString");
            DataTable dt = sdo.ExecuteQuery("select Id, Name, BirthInfo, ZipCode, [Address], HomeTelephone, CompanyTelephone, Mobile, Company, convert(char(10), RegDate, 120) as RegDate from [dbo].[tbl_contacts]");

            listView1.Items.Clear();

            if (dt.Rows.Count > 0)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    ListViewItem item = new ListViewItem();
                    item.Text = dr[0].ToString();
                    for (int i = 1; i < dt.Columns.Count; i++)
                    {
                        item.SubItems.Add(dr[i].ToString());
                    }
                    listView1.Items.Add(item);
                }
            }
            
            dt.Dispose();
            sdo.Dispose();


소스 파일 : 

ListViewExample1.zip


'C# with ListView' 카테고리의 다른 글

페이지 나누기가 있는 ListView  (0) 2015.05.07
Column Sorting 이 있는 ListView  (0) 2015.04.30
posted by 따시쿵
2015. 4. 27. 16:29 C# with DataGridView

프로그램 설명


DataGridView 칼럼을 sorting 하는 예제입니다.

SortableBindingList class 를 이용하며 BindingList class 에서 상속받은 것이며, PropertyComparer class 는 IComparer class 를 상속하여 구현하였습니다.


실행 후


1. 정렬을 하지 않은 경우


2. 정렬을 한 경우


프로그램 작성 순서


1. 라이브러리 클래스


SortableBindingList.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using Be.Timvw.Framework.Collections.Generic;

namespace Be.Timvw.Framework.ComponentModel
{
    public class SortableBindingList<t> : BindingList<t>
    {
        private readonly Dictionary<type, propertycomparer<t>> comparers;
        private bool isSorted;
        private ListSortDirection listSortDirection;
        private PropertyDescriptor propertyDescriptor;

        public SortableBindingList()
            : base(new List<t>())
        {
            this.comparers = new Dictionary<type, propertycomparer<t>>();
        }

        public SortableBindingList(IEnumerable<t> enumeration)
            : base(new List<t>(enumeration))
        {
            this.comparers = new Dictionary<type, propertycomparer<t>>();
        }

        protected override bool SupportsSortingCore
        {
            get { return true; }
        }

        protected override bool IsSortedCore
        {
            get { return this.isSorted; }
        }

        protected override PropertyDescriptor SortPropertyCore
        {
            get { return this.propertyDescriptor; }
        }

        protected override ListSortDirection SortDirectionCore
        {
            get { return this.listSortDirection; }
        }

        protected override bool SupportsSearchingCore
        {
            get { return true; }
        }

        protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
        {
            List<t> itemsList = (List<t>)this.Items;

            Type propertyType = property.PropertyType;
            PropertyComparer<t> comparer;
            if (!this.comparers.TryGetValue(propertyType, out comparer))
            {
                comparer = new PropertyComparer<t>(property, direction);
                this.comparers.Add(propertyType, comparer);
            }

            comparer.SetPropertyAndDirection(property, direction);
            itemsList.Sort(comparer);

            this.propertyDescriptor = property;
            this.listSortDirection = direction;
            this.isSorted = true;

            this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
        }

        protected override void RemoveSortCore()
        {
            this.isSorted = false;
            this.propertyDescriptor = base.SortPropertyCore;
            this.listSortDirection = base.SortDirectionCore;

            this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
        }

        protected override int FindCore(PropertyDescriptor property, object key)
        {
            int count = this.Count;
            for (int i = 0; i < count; ++i)
            {
                T element = this[i];
                if (property.GetValue(element).Equals(key))
                {
                    return i;
                }
            }

            return -1;
        }
    }
}


PropertyComparer.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;

namespace Be.Timvw.Framework.Collections.Generic
{
    public class PropertyComparer<t> : IComparer<t>
    {
        private readonly IComparer comparer;
        private PropertyDescriptor propertyDescriptor;
        private int reverse;

        public PropertyComparer(PropertyDescriptor property, ListSortDirection direction)
        {
            this.propertyDescriptor = property;
            Type comparerForPropertyType = typeof(Comparer<>).MakeGenericType(property.PropertyType);
            this.comparer = (IComparer)comparerForPropertyType.InvokeMember("Default", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public, null, null, null);
            this.SetListSortDirection(direction);
        }

        #region IComparer<t> Members

        public int Compare(T x, T y)
        {
            return this.reverse * this.comparer.Compare(this.propertyDescriptor.GetValue(x), this.propertyDescriptor.GetValue(y));
        }

        #endregion

        private void SetPropertyDescriptor(PropertyDescriptor descriptor)
        {
            this.propertyDescriptor = descriptor;
        }

        private void SetListSortDirection(ListSortDirection direction)
        {
            this.reverse = direction == ListSortDirection.Ascending ? 1 : -1;
        }

        public void SetPropertyAndDirection(PropertyDescriptor descriptor, ListSortDirection direction)
        {
            this.SetPropertyDescriptor(descriptor);
            this.SetListSortDirection(direction);
        }
    }
}


2. 사용하는 방법

        private void RebindGridForPageChange()
        {
            //Rebinding the Datagridview with data
            int datasourcestartIndex = (CurrentPage - 1) * PageRows;
            Templist = new List<contacts>();
            for (int i = datasourcestartIndex; i < datasourcestartIndex + PageRows; i++)
            {
                if (i >= Baselist.Count)
                    break;

                Templist.Add(Baselist[i]);
            }

            //Set List data to SortableBindingList 
            SortableBindingList<contacts> plist = new SortableBindingList<contacts>(Templist);

            dataGridView1.DataSource = plist;
            dataGridView1.Refresh();
        }


소스 파일 : 

DataGridViewExample3.zip

posted by 따시쿵
2015. 4. 24. 16:11 C# with DataGridView
프로그램 설명

한 화면에 20개의 데이타를 보여주고, 페이지 번호가 있어서 각 페이지로 바로 이동 할 수 있는 예제입니다. 데이타는 데이타베이스에 10,000 개의 데이타를 임의로 입력하고 쿼리를 통해서 가져오는 방법입니다.

전체적인 로직은 System.ComponentModel.BindingList 를 이용해서, 전체 데이타를 가져오고 난 후에 각 페이지로 이동 할 때에 전체 데이타에서 해당하는 데이타 20개씩을 화면에 보여줍니다.

데이타베이스 화면



실행 화면


1. 첫화면 로딩이 마친 후



2. 페이지 이동을 13 페이지로 한 후



프로그램 작성


소스 파일안에 주석을 달아 놓았으니 확인 해 보시면 됩니다.

    public partial class MainForm : Form
    {
        #region Initialize fields
        private int CurrentPage = 1;
        int PagesCount = 1;
        int PageRows = 20;

        BindingList<contacts> Baselist = null;
        BindingList<contacts> Templist = null;
        #endregion

        #region InitialIze MainForm()
        public MainForm()
        {
            InitializeComponent();
        }

        /// 
        /// Call MainForm
        /// 
        /// 
        /// 
        private void MainForm_Load(object sender, EventArgs e)
        {
            Baselist = FillDataforGrid();
            PagesCount = Convert.ToInt32(Math.Ceiling(Baselist.Count * 1.0 / PageRows));
            
            DataGridViewHeaderSetting();

            CurrentPage = 1;
            RefreshPagination();
            RebindGridForPageChange();
        }

        /// 
        /// Get all contacts database data
        /// 
        /// 
        private BindingList<contacts> FillDataforGrid()
        {
            SQLOperator sdo = new SQLOperator("SampleDBConnectionString");
            DataTable dt = sdo.ExecuteQuery(@"select Id, Name, BirthInfo, ZipCode, [Address], HomeTelephone, 
                                                     CompanyTelephone, Mobile, Company, convert(char(10), RegDate, 120) as RegDate
                                              from [dbo].[tbl_contacts]");

            BindingList<contacts> pContact = new BindingList<contacts>();

            if (dt.Rows.Count > 0)
            {
                foreach (DataRow row in dt.Rows)
                {
                    pContact.Add(new Contacts()
                    {
                        Idx = Convert.ToInt32(row["Id"]),
                        Name = row["Name"].ToString(),
                        BirthInfo = row["BirthInfo"].ToString(),
                        ZipCode = row["ZipCode"].ToString(),
                        Address = row["Address"].ToString(),
                        HomeTelephone = row["HomeTelephone"].ToString(),
                        CompanyTelephone = row["CompanyTelephone"].ToString(),
                        Mobile = row["Mobile"].ToString(),
                        Company = row["Company"].ToString(),
                        RegDate = row["RegDate"].ToString()
                    });
                }
            }

            return pContact;
        }

        #endregion

        #region Button Events
        /// 
        /// Exit button
        /// 
        /// 
        /// 
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(MessageBox.Show(Properties.Resources.TerminateConfirmMsg, "확인", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes )
                this.Close();
        }

        /// 
        /// ToolstripButton(처음으로, 앞으로, 1, 2, 3, 4, 5, 뒤로, 마지막으로)
        /// 
        /// 
        /// 
        private void ToolStripButtonClick(object sender, EventArgs e)
        {
            try
            {
                ToolStripButton ToolStripButton = ((ToolStripButton)sender);

                //Determining the current page
                if (ToolStripButton == btnBackward)
                    CurrentPage--;
                else if (ToolStripButton == btnForward)
                    CurrentPage++;
                else if (ToolStripButton == btnLast)
                    CurrentPage = PagesCount;
                else if (ToolStripButton == btnFirst)
                    CurrentPage = 1;
                else
                    CurrentPage = Convert.ToInt32(ToolStripButton.Text, CultureInfo.InvariantCulture);

                if (CurrentPage < 1)
                    CurrentPage = 1;
                else if (CurrentPage > PagesCount)
                    CurrentPage = PagesCount;

                //Rebind the Datagridview with the data.
                RebindGridForPageChange();

                //Change the pagiantions buttons according to page number
                RefreshPagination();
            }
            catch (Exception) { }
        }
        #endregion

        #region Page setting
        private void RefreshPagination()
        {
            ToolStripButton[] items = new ToolStripButton[] { toolStripButton1, toolStripButton2, toolStripButton3, toolStripButton4, toolStripButton5 };

            //pageStartIndex contains the first button number of pagination.
            int pageStartIndex = 1;

            if (PagesCount > 5 && CurrentPage > 2)
                pageStartIndex = CurrentPage - 2;

            if (PagesCount > 5 && CurrentPage > PagesCount - 2)
                pageStartIndex = PagesCount - 4;

            for (int i = pageStartIndex; i < pageStartIndex + 5; i++)
            {
                if (i > PagesCount)
                {
                    items[i - pageStartIndex].Visible = false;
                }
                else
                {
                    //Changing the page numbers
                    items[i - pageStartIndex].Text = i.ToString(CultureInfo.InvariantCulture);

                    //Setting the Appearance of the page number buttons
                    if (i == CurrentPage)
                    {
                        items[i - pageStartIndex].BackColor = Color.Black;
                        items[i - pageStartIndex].ForeColor = Color.White;
                    }
                    else
                    {
                        items[i - pageStartIndex].BackColor = Color.White;
                        items[i - pageStartIndex].ForeColor = Color.Black;
                    }
                }
            }

            //Enabling or Disalbing pagination first, last, previous , next buttons
            if (CurrentPage == 1)
                btnBackward.Enabled = btnFirst.Enabled = false;
            else
                btnBackward.Enabled = btnFirst.Enabled = true;

            if (CurrentPage == PagesCount)
                btnForward.Enabled = btnLast.Enabled = false;

            else
                btnForward.Enabled = btnLast.Enabled = true;
        }
        #endregion

        #region Get data in current page
        private void RebindGridForPageChange()
        {
            //Rebinding the Datagridview with data
            int datasourcestartIndex = (CurrentPage - 1) * PageRows;
            Templist = new BindingList<contacts>();
            for (int i = datasourcestartIndex; i < datasourcestartIndex + PageRows; i++)
            {
                if (i >= Baselist.Count)
                    break;

                Templist.Add(Baselist[i]);
            }

            dataGridView1.DataSource = Templist;
            dataGridView1.Refresh();
        }
        #endregion

        #region DataGridView Header Setting
        /// 
        /// Set DataGridView header text and property(text align, font size)
        /// 
        private void DataGridViewHeaderSetting()
        {
            dataGridView1.AutoGenerateColumns = false;
            

            DataGridViewTextBoxColumn IdxColumn = new DataGridViewTextBoxColumn();
            IdxColumn.DataPropertyName = "Idx";
            IdxColumn.HeaderText = "No.";

            DataGridViewTextBoxColumn NameColumn = new DataGridViewTextBoxColumn();
            NameColumn.DataPropertyName = "Name";
            NameColumn.HeaderText = "이름";

            DataGridViewTextBoxColumn BirthInfoColumn = new DataGridViewTextBoxColumn();
            BirthInfoColumn.DataPropertyName = "BirthInfo";
            BirthInfoColumn.HeaderText = "생년월일";

            DataGridViewTextBoxColumn ZipCodeColumn = new DataGridViewTextBoxColumn();
            ZipCodeColumn.DataPropertyName = "ZipCode";
            ZipCodeColumn.HeaderText = "우편번호";

            DataGridViewTextBoxColumn AddressColumn = new DataGridViewTextBoxColumn();
            AddressColumn.DataPropertyName = "Address";
            AddressColumn.HeaderText = "주 소";

            DataGridViewTextBoxColumn HomeTelephoneColumn = new DataGridViewTextBoxColumn();
            HomeTelephoneColumn.DataPropertyName = "HomeTelephone";
            HomeTelephoneColumn.HeaderText = "집 전화번호";

            DataGridViewTextBoxColumn CompanyTelephoneColumn = new DataGridViewTextBoxColumn();
            CompanyTelephoneColumn.DataPropertyName = "CompanyTelephone";
            CompanyTelephoneColumn.HeaderText = "회사 전화번호";

            DataGridViewTextBoxColumn MobileColumn = new DataGridViewTextBoxColumn();
            MobileColumn.DataPropertyName = "Mobile";
            MobileColumn.HeaderText = "핸드폰번호";

            DataGridViewTextBoxColumn CompanyColumn = new DataGridViewTextBoxColumn();
            CompanyColumn.DataPropertyName = "Company";
            CompanyColumn.HeaderText = "회사명";

            DataGridViewTextBoxColumn RegDateColumn = new DataGridViewTextBoxColumn();
            RegDateColumn.DataPropertyName = "RegDate";
            RegDateColumn.HeaderText = "등록일";

            dataGridView1.Columns.Add(IdxColumn);
            dataGridView1.Columns.Add(NameColumn);
            dataGridView1.Columns.Add(BirthInfoColumn);
            dataGridView1.Columns.Add(ZipCodeColumn);
            dataGridView1.Columns.Add(AddressColumn);
            dataGridView1.Columns.Add(HomeTelephoneColumn);
            dataGridView1.Columns.Add(CompanyTelephoneColumn);
            dataGridView1.Columns.Add(MobileColumn);
            dataGridView1.Columns.Add(CompanyColumn);
            dataGridView1.Columns.Add(RegDateColumn);

            foreach (DataGridViewColumn col in dataGridView1.Columns)
            {
                col.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
                col.HeaderCell.Style.Font = new Font("Arial", 12F, FontStyle.Bold, GraphicsUnit.Pixel);
                col.HeaderCell.Style.ForeColor = Color.White;

                // Set the column size automatically
                col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            }

            // Set the header column BackColor
            dataGridView1.ColumnHeadersDefaultCellStyle.BackColor = Color.DarkOrange;
            dataGridView1.EnableHeadersVisualStyles = false;
        }
        #endregion
    }


소스 파일 :

DataGridViewExample2.zip


posted by 따시쿵
2015. 4. 22. 17:08 C# with DataGridView

프로그램 설명


DataGridView 의 datasource 와 List class를 이용하는 방법입니다.

데이타베이스 4칙 연산을 수행합니다.


Contacts class 는 아래와 같습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Windows.Forms;
using DataGridViewExample.lib;


namespace DataGridViewExample.data
{
    public class Contacts
    {
        #region Properties
        public int Idx { get; set; }
        public string Name { get; set; }
        public string BirthInfo { get; set; }
        public string ZipCode { get; set; }
        #endregion

        #region Functions
        /// 
        // Add the contacts info
        /// 
        /// 
        public bool AddContacts()
        {
            bool retval = false;
            try
            { 
                SQLOperator sdo = new SQLOperator("SampleDBConnectionString");

                string query = @"insert into [dbo].[tbl_contacts](Name, BirthInfo, ZipCode)
                                    values(@Name, @BirthInfo, @ZipCode);";

                sdo.ExecuteNoneQuery(query,
                                    new SqlParameter[]
                                    {
                                        new SqlParameter("@Name", Name),
                                        new SqlParameter("@BirthInfo", BirthInfo),
                                        new SqlParameter("@ZipCode", ZipCode)
                                    },
                                    CommandType.Text);
                sdo.Dispose();

                retval = true;
            }
            catch (SqlException se)
            {
                Trace.WriteLine(se.Message);
                retval = false;
            }
            catch(Exception ex)
            {
                Trace.WriteLine(ex.Message);
                retval = false;
            }

            return retval;
        }

        /// 
        /// Modify the contacts info
        /// 
        /// 
        public bool ModifyContacts()
        {
            bool retval = false;
            try
            {
                SQLOperator sdo = new SQLOperator("SampleDBConnectionString");

                string query = @"update [dbo].[tbl_contacts]
                                set  Name = @Name, BirthInfo = @BirthInfo, ZipCode = @ZipCode
                                where Id = @Idx;";

                sdo.ExecuteNoneQuery(query,
                                    new SqlParameter[]
                                    {
                                        new SqlParameter("@Name", Name),
                                        new SqlParameter("@BirthInfo", BirthInfo),
                                        new SqlParameter("@ZipCode", ZipCode),
                                        new SqlParameter("@Idx", Idx)
                                    },
                                    CommandType.Text);
                sdo.Dispose();

                retval = true;
            }
            catch (SqlException se)
            {
                Trace.WriteLine(se.Message);
                retval = false;
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
                retval = false;
            }

            return retval;
        }

        public bool RemoveContacts()
        {
            bool retval = false;
            try
            {
                SQLOperator sdo = new SQLOperator("SampleDBConnectionString");

                string query = @"delete from [dbo].[tbl_contacts]
                                where Id = @Idx;";

                sdo.ExecuteNoneQuery(query,
                                    new SqlParameter[]
                                    {
                                        new SqlParameter("@Idx", Idx)
                                    },
                                    CommandType.Text);
                sdo.Dispose();

                retval = true;
            }
            catch (SqlException se)
            {
                Trace.WriteLine(se.Message);
                retval = false;
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
                retval = false;
            }

            return retval;
        }
        #endregion
    }
}


실행 화면



소스 파일 

DataGridViewExample.zip


'C# with DataGridView' 카테고리의 다른 글

Column Sorting 이 있는 DataGridView  (0) 2015.04.27
페이지 나누기가 있는 DataGridView  (0) 2015.04.24
posted by 따시쿵
2015. 4. 22. 15:50 C#

데이타베이스 작업을 할시에 필요한 라이브러리를 소개합니다.

select, update, delete, insert 모두에 사용되며, ad-hoc 쿼리나 스토어프로시저 모두에 사용 가능합니다.


사용하는 방법

아래 예제는 모두 Contacts class 가 있어서, UI 버튼 클릭시 Contacts 클래스의 property 에 개별적인 값을 대입한 후, 필요한 작업을 수행합니다.

Contacts.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using DataGridViewExample.lib;

namespace DataGridViewExample.data
{
    public class Contacts
    {
        #region Properties
        public int Idx { get; set; }
        public string Name { get; set; }
        public string BirthInfo { get; set; }
        public string ZipCode { get; set; }
        #endregion

        #region Functions
        /// 
        // Add the contacts info
        /// 
        /// 
        public bool AddContacts()
        {
            bool retval = false;
            try
            { 
                SQLOperator sdo = new SQLOperator("SampleDBConnectionString");

                string query = @"insert into [dbo].[tbl_contacts](Name, BirthInfo, ZipCode)
                                    values(@Name, @BirthInfo, @ZipCode);";

                sdo.ExecuteNoneQuery(query,
                                    new SqlParameter[]
                                    {
                                        new SqlParameter("@Name", Name),
                                        new SqlParameter("@BirthInfo", BirthInfo),
                                        new SqlParameter("@ZipCode", ZipCode)
                                    },
                                    CommandType.Text);
                sdo.Dispose();

                retval = true;
            }
            catch (SqlException se)
            {
                Trace.WriteLine(se.Message);
                retval = false;
            }
            catch(Exception ex)
            {
                Trace.WriteLine(ex.Message);
                retval = false;
            }

            return retval;
        }

        /// 
        /// Modify the contacts info
        /// 
        /// 
        public bool ModifyContacts()
        {
            bool retval = false;
            try
            {
                SQLOperator sdo = new SQLOperator("SampleDBConnectionString");

                string query = @"update [dbo].[tbl_contacts]
                                set  Name = @Name, BirthInfo = @BirthInfo, ZipCode = @ZipCode
                                where Id = @Idx;";

                sdo.ExecuteNoneQuery(query,
                                    new SqlParameter[]
                                    {
                                        new SqlParameter("@Name", Name),
                                        new SqlParameter("@BirthInfo", BirthInfo),
                                        new SqlParameter("@ZipCode", ZipCode),
                                        new SqlParameter("@Idx", Idx)
                                    },
                                    CommandType.Text);
                sdo.Dispose();

                retval = true;
            }
            catch (SqlException se)
            {
                Trace.WriteLine(se.Message);
                retval = false;
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
                retval = false;
            }

            return retval;
        }

        public bool RemoveContacts()
        {
            bool retval = false;
            try
            {
                SQLOperator sdo = new SQLOperator("SampleDBConnectionString");

                string query = @"delete from [dbo].[tbl_contacts]
                                where Id = @Idx;";

                sdo.ExecuteNoneQuery(query,
                                    new SqlParameter[]
                                    {
                                        new SqlParameter("@Idx", Idx)
                                    },
                                    CommandType.Text);
                sdo.Dispose();

                retval = true;
            }
            catch (SqlException se)
            {
                Trace.WriteLine(se.Message);
                retval = false;
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
                retval = false;
            }

            return retval;
        }
        #endregion
    }
}


1. select 시


DataTable set 을 가져와서 DataGridView 의 DataSource 에 바인드 합니다.

            SQLOperator sdo = new SQLOperator("SampleDBConnectionString");
            DataTable dt = sdo.ExecuteQuery("select Id, Name, BirthInfo, ZipCode from [dbo].[tbl_contacts]");

            dataGridView1.DataSource = dt;

            dt.Dispose();
            sdo.Dispose();

DataTable set 을 가져와서 List에 넣는 후 DataGridView 의 DataSource 에 바인드 합니다.

            SQLOperator sdo = new SQLOperator("SampleDBConnectionString");
            DataTable dt = sdo.ExecuteQuery("select Id, Name, BirthInfo, ZipCode from [dbo].[tbl_contacts]");

            List<Contacts>  pContact = new List<Contacts>();
            if(dt.Rows.Count > 0)
            {
                foreach(DataRow row in dt.Rows)
                {
                    pContact.Add(new Contacts()
                        {
                            Idx = Convert.ToInt32(row["Id"]),
                            Name = row["Name"].ToString(),
                            BirthInfo = row["BirthInfo"].ToString(),
                            ZipCode = row["ZipCode"].ToString()
                        });
                }
            }

            dataGridView1.DataSource = pContact;

            dt.Dispose();
            sdo.Dispose();


2. update 시

            Contacts contact = new Contacts();

            contact.Idx = Convert.ToInt32(lblIdx.Text);
            contact.Name = txtName.Text.Trim();
            contact.BirthInfo = txtBirthInfo.Text.Trim();
            contact.ZipCode = txtZipCode.Text.Trim();

            if (contact.ModifyContacts())
            {
                toolStripStatusLabel1.Text = Properties.Resources.AddConfirmMsg;
            }
            else
            {
                toolStripStatusLabel1.Text = Properties.Resources.AddErrorMsg;
            }


3. delete 시

            Contacts contact = new Contacts();

            contact.Idx = Convert.ToInt32(lblIdx.Text);
            string message = string.Format("[{0}] 정보를 삭제하시겠습니까", txtName.Text.Trim());

            if (MessageBox.Show(message, "확인", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.OK)
            { 
                if (contact.RemoveContacts())
                {
                    toolStripStatusLabel1.Text = Properties.Resources.RemoveConfirmMsg;
                }
                else
                {
                    toolStripStatusLabel1.Text = Properties.Resources.RemoveErrorMsg;
                }
            }



4. insert 시

            Contacts contact = new Contacts();

            contact.Name = txtName.Text.Trim();
            contact.BirthInfo = txtBirthInfo.Text.Trim();
            contact.ZipCode = txtZipCode.Text.Trim();

            if (contact.AddContacts())
            {
                toolStripStatusLabel1.Text = Properties.Resources.AddConfirmMsg;
            }
            else 
            { 
                toolStripStatusLabel1.Text = Properties.Resources.AddErrorMsg;
            }




데이타베이스 라이브러리는 아래와 같습니다.

SQLOperator.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace DataGridViewExample.lib
{
    /// 


/// Summary description for SqlDataOperator /// public class SQLOperator : IDisposable { private SqlConnection conn; private SqlCommand comm; private SqlDataAdapter adap; private SqlTransaction tran; public SqlConnection Connection { get { return conn; } set { conn = value; } } public SqlCommand Command { get { return comm; } set { comm = value; } } public SqlTransaction Transaction { get { return tran; } } public SQLOperator() : this("default") { } public SQLOperator(string connectionStringName) { conn = new SqlConnection(ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString); //conn = new SqlConnection(Properties.Settings.Default.SampleDBConnectionString); comm = new SqlCommand(); comm.Connection = conn; adap = new SqlDataAdapter(); } public SqlTransaction BeginTransaction() { if (conn.State == ConnectionState.Closed) conn.Open(); tran = conn.BeginTransaction(); return tran; } public void RollBackTran() { if (tran != null) tran.Rollback(); } public void CommitTran() { if (tran != null) tran.Commit(); } public SqlDataReader ExecuteReader(string query, SqlParameter[] parameters, CommandType commType) { comm.CommandType = commType; comm.CommandText = query; AddParameters(parameters); if (conn.State == ConnectionState.Closed) conn.Open(); SqlDataReader dr = comm.ExecuteReader(CommandBehavior.CloseConnection); return dr; } public SqlDataReader ExecuteReader(string spName, SqlParameter[] parameters) { comm.CommandType = CommandType.StoredProcedure; comm.CommandText = spName; AddParameters(parameters); if (conn.State == ConnectionState.Closed) conn.Open(); SqlDataReader dr = comm.ExecuteReader(CommandBehavior.CloseConnection); return dr; } public SqlDataReader ExecuteReader(string query) { comm.CommandType = CommandType.Text; comm.CommandText = query; if (conn.State == ConnectionState.Closed) conn.Open(); SqlDataReader dr = comm.ExecuteReader(CommandBehavior.CloseConnection); return dr; } public object ExecuteScalar(string sql) { comm.CommandText = sql; comm.CommandType = CommandType.Text; if (conn.State == ConnectionState.Closed) conn.Open(); object result = comm.ExecuteScalar(); comm.Parameters.Clear(); return result; } public object ExecuteScalar(string spName, SqlParameter[] parameters) { comm.CommandText = spName; comm.CommandType = CommandType.StoredProcedure; AddParameters(parameters); if (conn.State == ConnectionState.Closed) conn.Open(); object result = comm.ExecuteScalar(); comm.Parameters.Clear(); return result; } public object ExecuteScalar(string spName, SqlParameter[] parameters, CommandType commType) { comm.CommandText = spName; comm.CommandType = commType; AddParameters(parameters); if (conn.State == ConnectionState.Closed) conn.Open(); object result = comm.ExecuteScalar(); comm.Parameters.Clear(); return result; } public object ExecuteScalar(string spName, SqlParameter[] parameters, CommandType commType, SqlTransaction tran) { comm.Transaction = tran; return ExecuteScalar(spName, parameters, commType); } public object ExecuteScalar(string spName, SqlParameter[] parameters, SqlTransaction tran) { comm.Transaction = tran; return ExecuteScalar(spName, parameters); } public void ExecuteNoneQuery(string spName, SqlParameter[] parameters) { comm.CommandText = spName; comm.CommandType = CommandType.StoredProcedure; AddParameters(parameters); SqlParameter para = new SqlParameter("@RETURN_VALUE", SqlDbType.Int); para.Direction = ParameterDirection.ReturnValue; comm.Parameters.Add(para); if (conn.State == ConnectionState.Closed) conn.Open(); comm.ExecuteNonQuery(); comm.Parameters.Clear(); } public void ExecuteNoneQuery(string spName, SqlParameter[] parameters, CommandType commType) { comm.CommandText = spName; comm.CommandType = commType; AddParameters(parameters); SqlParameter para = new SqlParameter("@RETURN_VALUE", SqlDbType.Int); para.Direction = ParameterDirection.ReturnValue; comm.Parameters.Add(para); if (conn.State == ConnectionState.Closed) conn.Open(); comm.ExecuteNonQuery(); comm.Parameters.Clear(); } public int ExecuteNoneQuery_Retrun_Param(string spName, SqlParameter[] parameters, CommandType commType) { comm.CommandText = spName; comm.CommandType = commType; AddParameters(parameters); SqlParameter para = new SqlParameter("@RETURN_VALUE", SqlDbType.Int); para.Direction = ParameterDirection.ReturnValue; SqlParameter return_param = comm.Parameters.Add(para); if (conn.State == ConnectionState.Closed) conn.Open(); comm.ExecuteNonQuery(); var return_param_1 = return_param.Value; comm.Parameters.Clear(); return (int)return_param_1; } public void ExecuteNoneQuery(string spName, SqlParameter[] parameters, CommandType commType, SqlTransaction tran) { comm.Transaction = tran; ExecuteNoneQuery(spName, parameters, commType); } public void ExecuteNoneQuery(string spName, SqlParameter[] parameters, SqlTransaction tran) { comm.Transaction = tran; ExecuteNoneQuery(spName, parameters); } public void ExecuteNoneQuery(string sql, SqlTransaction tran) { comm.Transaction = tran; ExecuteNoneQuery(sql); } public void ExecuteNoneQuery(string sql) { comm.CommandText = sql; comm.CommandType = CommandType.Text; if (conn.State == ConnectionState.Closed) conn.Open(); comm.ExecuteNonQuery(); } public DataTable ExecuteQuery(string tableName, string spName, SqlParameter[] parameters) { DataTable dtResult = new DataTable(tableName); comm.CommandText = spName; comm.CommandType = CommandType.StoredProcedure; AddParameters(parameters); adap.SelectCommand = comm; if (conn.State == ConnectionState.Closed) conn.Open(); adap.Fill(dtResult); comm.Parameters.Clear(); return dtResult; } public DataTable ExecuteQuery(string tableName, string spName, SqlParameter[] parameters, CommandType commType) { DataTable dtResult = new DataTable(tableName); comm.CommandText = spName; comm.CommandType = commType; AddParameters(parameters); adap.SelectCommand = comm; if (conn.State == ConnectionState.Closed) conn.Open(); adap.Fill(dtResult); comm.Parameters.Clear(); return dtResult; } public DataSet ExecuteQueryToDS(string spName, SqlParameter[] parameters) { DataSet dsResult = new DataSet(); comm.CommandText = spName; comm.CommandType = CommandType.StoredProcedure; AddParameters(parameters); adap.SelectCommand = comm; if (conn.State == ConnectionState.Closed) conn.Open(); adap.Fill(dsResult); comm.Parameters.Clear(); return dsResult; } public DataTable ExecuteQuery(string tableName, string sql) { DataTable dtResult = ExecuteQuery(sql); dtResult.TableName = tableName; return dtResult; } public DataTable ExecuteQuery(string sql) { DataTable dtResult = new DataTable(); comm.CommandText = sql; comm.CommandType = CommandType.Text; adap.SelectCommand = comm; if (conn.State == ConnectionState.Closed) conn.Open(); adap.Fill(dtResult); return dtResult; } private void AddParameters(SqlParameter[] parameters) { comm.Parameters.Clear(); foreach (SqlParameter parameter in parameters) { comm.Parameters.Add(parameter); } } public string AntiInjection(string val) { val = RemoveScriptTag(val).Replace("'", "''"); return val; } public static string RemoveScriptTag(string s) { System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("(?<capture><[/]?script[a-zA-Z_0-9=\"\'\\s]*>)"); System.Text.RegularExpressions.MatchEvaluator evaluator = new System.Text.RegularExpressions.MatchEvaluator(MatchReplace); return reg.Replace(s, evaluator); } public static string MatchReplace(System.Text.RegularExpressions.Match m) { string s = m.Groups["capture"].Value; s = s.Replace("<", "<").Replace(">", ">"); return s; } #region IDisposable 멤버 public void Dispose() { comm.Parameters.Clear(); if (conn.State == ConnectionState.Open) conn.Close(); } #endregion } }

'C#' 카테고리의 다른 글

로그인 창  (0) 2015.05.08
멀티플(multiple) 윈도우 - 2  (0) 2015.05.07
BackgroundWorker class  (0) 2015.03.02
텍스트 로그 파일 라이브러리 - 3  (0) 2015.02.21
텍스트 로그 파일 라이브러리 - 2  (0) 2015.02.21
posted by 따시쿵
2015. 4. 2. 14:42 C# with TCP/IP

프로그램 설명


텍스트와 이미지 파일을 전송하는 예제입니다.

규칙은 아래 그림과 같습니다.



실행 후



연결 후



텍스트 전송 후



이미지 파일 전송 후




프로그램 작성 순서


1. 서버 프로그램

전체 소스는 아래에 있으며, 핵심적인 내용의 소스만 갈무리해서 올립니다.

AsyncSocketServer.zip

        public void ReceiveAsync()
        {
            socket.BeginReceive(lenBuffer, 0, lenBuffer.Length, SocketFlags.None, receiveCallBack, null);
        }

        public void receiveCallBack(IAsyncResult ar)
        {
            try
            {
                int rec = socket.EndReceive(ar);

                if (rec == 0)
                {
                    if (Disconnected != null)
                    {
                        Disconnected(this);
                        return;
                    }
                }

                if (rec != 4)
                {
                    throw new Exception();
                }
            }
            catch(SocketException se)
            {
                switch(se.SocketErrorCode)
                {
                    case SocketError.ConnectionAborted:
                    case SocketError.ConnectionReset:
                        if (Disconnected != null)
                        {
                            Disconnected(this);
                            return;
                        }
                        break;
                }
            }
            catch(ObjectDisposedException)
            {
                return;
            }
            catch(NullReferenceException)
            {
                return;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }

            buffer = new ReceiveBuffer(BitConverter.ToInt32(lenBuffer, 0));

            socket.BeginReceive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None, receivePacketCallBack, null);
        }

        public void receivePacketCallBack(IAsyncResult ar)
        {
            int rec = socket.EndReceive(ar);

            if (rec <= 0)
            {
                return;
            }

            buffer.BufStream.Write(buffer.Buffer, 0, rec);

            buffer.ToReceive -= rec;

            if (buffer.ToReceive > 0)
            {
                Array.Clear(buffer.Buffer, 0, buffer.Buffer.Length);

                socket.BeginReceive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None, receivePacketCallBack, null);
                return;
            }

            if (DataReceived != null)
            {
                buffer.BufStream.Position = 0;
                DataReceived(this, buffer);
            }

            buffer.Dispose();

            ReceiveAsync();
        }


2. 클라이언트 프로그램

전체 소스는 아래에 있으며, 핵심적인 내용의 소스만 갈무리해서 올립니다.


AsyncSocketClient.zip

        void SendText(string text)
        {
            BinaryWriter bw = new BinaryWriter(new MemoryStream());
            bw.Write((int)Commands.String);
            bw.Write(text);
            byte[] data = ((MemoryStream)bw.BaseStream).ToArray();
            bw.BaseStream.Dispose();
            client.Send(data, 0, data.Length);
            data = null;
        }

        void SendImage(string path)
        {
            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);
            byte[] b = File.ReadAllBytes(path);
            bw.Write((int)Commands.Image);
            bw.Write((int)b.Length);
            bw.Write(b);
            bw.Close();
            b = ms.ToArray();
            ms.Dispose();

            client.Send(b, 0, b.Length);
        }
posted by 따시쿵
2015. 3. 26. 13:45 C# with TCP/IP

프로그램 설명


바이트 배열을 이용한 파일 전송을 구현한 예시입니다.

이미지 파일 전송시 데이타 구조와 일반 텍스트 데이타 구조가 다르므로 아래에 그림으로 표시했습니다.

실행 후




이미지 파일 전송 후



메시지 전송 후




프로그램 작성


1. 데이타 버퍼 클래스 (StateObject.cs)


    class StateObject
    {
        // Client socket
        public Socket workSocket = null;

        public const int BufferSize = 4096;

        // Receive buffer
        public byte[] buffer = new byte[BufferSize];
    }


2. 서버 프로그램


    public partial class MainForm : Form
    {
        bool initialFlag = true;
        string receivedPath = string.Empty;
        enum DataPacketType { TEXT = 1, IMAGE };
        int dataType = 0;
        string textData = string.Empty;

        public MainForm()
        {
            InitializeComponent();

            Thread t_handler = new Thread(StartListening);
            t_handler.IsBackground = true;
            t_handler.Start();
        }

        public static ManualResetEvent allDone = new ManualResetEvent(false);
        private void StartListening()
        {
            IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 9050);
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                listener.Bind(localEP);
                listener.Listen(10);

                while(true)
                {
                    allDone.Reset();
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                    allDone.WaitOne();
                }
            }
            catch(SocketException se)
            {
                Trace.WriteLine(string.Format("SocketException :{0}", se.Message));
            }
            catch(Exception ex)
            {
                Trace.WriteLine(string.Format("Exception :{0}", ex.Message));
            }
        }

        private void AcceptCallback(IAsyncResult ar)
        {
            allDone.Set();

            Socket listener = ar.AsyncState as Socket;
            Socket handler = listener.EndAccept(ar);

            StateObject state = new StateObject();
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
            initialFlag = true;
        }

        private void ReadCallback(IAsyncResult ar)
        {
            int fileNameLen = 0;
            string content = string.Empty;
            StateObject state = ar.AsyncState as StateObject;
            Socket handler = state.workSocket;
            int bytesRead = handler.EndReceive(ar);
            
            if(bytesRead > 0)
            {                
                if (initialFlag)
                {
                    dataType = BitConverter.ToInt32(state.buffer, 0);
                    if (dataType == (int)DataPacketType.IMAGE)
                    { 
                        fileNameLen = BitConverter.ToInt32(state.buffer, 4);
                        string fileName = Encoding.UTF8.GetString(state.buffer, 8, fileNameLen);

                        string pathUser = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
                        string pathDownload = Path.Combine(pathUser, "Downloads");

                        receivedPath = Path.Combine(pathDownload, fileName);

                        if (File.Exists(receivedPath))
                            File.Delete(receivedPath);
                    }
                    else if (dataType == (int)DataPacketType.TEXT)
                    {
                        textData = Encoding.UTF8.GetString(state.buffer, 4, bytesRead - 4);
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                    }
                }

                if (dataType == (int)DataPacketType.IMAGE)
                {
                    BinaryWriter bw = new BinaryWriter(File.Open(receivedPath, FileMode.Append));
                    if (initialFlag)
                        bw.Write(state.buffer, 8 + fileNameLen, bytesRead - (8 + fileNameLen));
                    else
                        bw.Write(state.buffer, 0, bytesRead);

                    initialFlag = false;
                    bw.Close();
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                }
            }
            else
            {
                if (dataType == (int)DataPacketType.IMAGE)
                {
                    pictureBox1.ImageLocation = receivedPath;
                    Invoke((MethodInvoker)delegate
                    {
                        lblMessage.Text = "Data has been received";
                    });
                }
                else if (dataType == (int)DataPacketType.TEXT)
                    Invoke((MethodInvoker)delegate
                    {
                        textBox1.AppendText(textData + Environment.NewLine);
                    });
            }
        }
    }


3. 클라이언트 프로그램


    public partial class MainForm : Form
    {
        string m_splitter = "'\\'";
        string m_fName = string.Empty;
        string[] m_split = null;
        byte[] m_clientData = null;
        enum DataPacketType { TEXT = 1, IMAGE };

        public MainForm()
        {
            InitializeComponent();
            
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            char[] delimeter = m_splitter.ToCharArray();

            openFileDialog1.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";
            openFileDialog1.ShowDialog();

            textBox1.Text = openFileDialog1.FileName;
            pictureBox1.ImageLocation = openFileDialog1.FileName;

            m_split = textBox1.Text.Split(delimeter);
            int limit = m_split.Length;

            m_fName = m_split[limit - 1].ToString();

            if (textBox1.Text != null)
                btnSend.Enabled = true;
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            Thread t_handler = new Thread(SendData);
            t_handler.IsBackground = true;
            t_handler.Start();
        }

        private void SendData()
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            byte[] fileName = Encoding.UTF8.GetBytes(m_fName);
            byte[] fileData = File.ReadAllBytes(textBox1.Text);
            byte[] fileNameLen = BitConverter.GetBytes(fileName.Length);
            byte[] fileType = BitConverter.GetBytes((int)DataPacketType.IMAGE);
            // IMAGE(4 byte) + 파일이름(4 byte) + 파일이름길이(4 byte) + 데이타 길이
            m_clientData = new byte[fileType.Length + 4 + fileName.Length + fileData.Length];

            fileType.CopyTo(m_clientData, 0);
            fileNameLen.CopyTo(m_clientData, 4);
            fileName.CopyTo(m_clientData, 8);
            fileData.CopyTo(m_clientData, 8 + fileName.Length);
            
            clientSocket.Connect(IPAddress.Parse("192.168.0.11"), 9050);
            clientSocket.Send(m_clientData);
            clientSocket.Close();
        }

        private void btnSendText_Click(object sender, EventArgs e)
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            byte[] textData = Encoding.UTF8.GetBytes(textBox2.Text);
            byte[] fileType = BitConverter.GetBytes((int)DataPacketType.TEXT);
            // TEXT(4 byte) + 데이타 길이
            m_clientData = new byte[fileType.Length + textData.Length];

            fileType.CopyTo(m_clientData, 0);
            textData.CopyTo(m_clientData, 4);

            clientSocket.Connect(IPAddress.Parse("192.168.0.11"), 9050);
            clientSocket.Send(m_clientData);
            clientSocket.Close();
        }
    }

posted by 따시쿵
2015. 3. 20. 18:00 C# with TCP/IP

프로그램 설명


SslStream 클래스를 이용한 통신 방법으로 구현 되었습니다.


보안이 없는 일반 tcp 서버/클라이언트와 비교해서 다른 점은 데이타를 주고 받기 전에 반드시 SSL 핸드세이크의 단계를 거친다는 점입니다.


아래는 msdn 에서 발취한 내용입니다.

https://msdn.microsoft.com/ko-kr/library/system.net.security.sslstream(v=vs.110).aspx

SSL 핸드셰이크라고도 하는 인증 프로세스가 성공하면 서버와 클라이언트(선택적)의 ID가 설정되고 클라이언트와 서버는 SslStream을 사용하여 메시지를 주고받을 수 있습니다. 정보를 보내거나 받기 전에 클라이언트와 서버에서는 SslStream에 제공되는 보안 서비스 및 수준을 확인하여, 선택한 프로토콜, 알고리즘 및 강도가 무결성 및 기밀성 요구 사항을 충족하는지 확인해야 합니다.


작업을 하기 전에 인증서를 만드는 방법을 알고 개발에 사용할 인증서를 만들어야 합니다.


1.

Makecert.exe (Certificate Creation Tool) 사이트에서 다음의 예제와 같이 도스 창에서 명령어를 실행해서 작성합니다.


makecert -r -pe -n "CN=XYZ Company" -b 01/01/2005 -e 01/01/2010 -sky exchange -ss my


makecert 파일은 Windows 8.1 을 기준으로 아래의 경로에 있습니다.


 


2.

Visual Studio 를 이용해서 인증서를 테스트 할 수 있는 환경, 즉 사용할 수 있는 인증서로 만듭니다.








여기에 보여지는 소스는 msdn 사이트에 나오는 소스이며 원본 사이트는 아래와 같습니다.

https://msdn.microsoft.com/ko-kr/library/system.net.security.sslstream(v=vs.110).aspx



실행 후




메시지 전송 후




프로그램 작성 방법


1. 서버 프로그램


using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Diagnostics;

    public sealed class SslTcpServer
    {
        static X509Certificate serverCertificate = null;

        public static void RunServer(string certificate, string password)
        {
            try
            {
                serverCertificate = new X509Certificate(certificate, password);
                
                TcpListener listener = new TcpListener(IPAddress.Any, 8080);
                listener.Start();

                while(true)
                {
                    Console.WriteLine("Waiting for a client to connect...");
                    Console.WriteLine();

                    TcpClient client = listener.AcceptTcpClient();
                    ProcessClient(client);
                }
            }
            catch(Exception ex)
            {
                Trace.WriteLine(string.Format("Error : {0}", ex.Message));
            }
        }

        static void ProcessClient(TcpClient client)
        {
            SslStream sslStream = new SslStream(client.GetStream(), false);

            try
            {
                sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);
                
                // Set timeouts for the read and write to 5 seconds.
                //sslStream.ReadTimeout = 5000;
                //sslStream.WriteTimeout = 5000;

                // Read a message from the client.
                Console.WriteLine("Waiting for client message...");
                string messageData = ReadMessage(sslStream);
                Console.WriteLine("Received : {0}", messageData.Substring(0, messageData.IndexOf("$")));

                // Write a message to the client
                messageData = "[reply] " + messageData;
                byte[] message = Encoding.UTF8.GetBytes(messageData);
                sslStream.Write(message);
                Console.WriteLine("Sending hello message");
                Console.WriteLine();
            }
            catch (AuthenticationException e)
            {
                Console.WriteLine("Exception: {0}", e.Message);
                if (e.InnerException != null)
                {
                    Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                }
                Console.WriteLine("Authentication failed - closing the connection.");
                sslStream.Close();
                client.Close();
                return;
            }
            finally
            {
                // The client stream will be closed with the sslStream
                // because we specified this behavior when creating
                // the sslStream.
                sslStream.Close();
                client.Close();
            }
        }

        static string ReadMessage(SslStream sslStream)
        {
            // Read the  message sent by the client.
            // The client signals the end of the message using the
            // "$" marker.
            byte[] buffer = new byte[2048];
            StringBuilder messageData = new StringBuilder();
            int bytes = -1;
            do
            {
                // Read the client's test message.
                bytes = sslStream.Read(buffer, 0, buffer.Length);

                // Use Decoder class to convert from bytes to UTF8
                // in case a character spans two buffers.
                Decoder decoder = Encoding.UTF8.GetDecoder();
                char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
                decoder.GetChars(buffer, 0, bytes, chars, 0);
                messageData.Append(chars);
                // Check for EOF or an empty message.
                if (messageData.ToString().IndexOf("$") != -1)
                {
                    break;
                }
            } while (bytes != 0);

            return messageData.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            SslTcpServer.RunServer("XYZ_Company_ver2.pfx", "agrafood01");

            Console.WriteLine("Press the any key to continue...");
            Console.ReadLine();
        }
    }


2. 클라이언트 프로그램


using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Diagnostics;
using System.Collections;

    public class SslTcpClient
    {
        private static Hashtable certtificateError = new Hashtable();

        // The following method is invoked by the RemoteCertificateValidationDelegate.
        public static bool ValidateServerCertificate(
              object sender,
              X509Certificate certificate,
              X509Chain chain,
              SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;

            Console.WriteLine("Certificate error: {0}", sslPolicyErrors);

            // Do not allow this client to communicate with unauthenticated servers.
            return false;
        }

        public static void RunClient(string machineName, string serverName, string inputMessage)
        {
            // Create a TCP/IP client socket.
            // machineName is the host running the server application.
            TcpClient client = new TcpClient(machineName, 8080);
            Console.WriteLine("Client connected.");
            // Create an SSL stream that will close the client's stream.
            SslStream sslStream = new SslStream(
                client.GetStream(),
                false,
                new RemoteCertificateValidationCallback(ValidateServerCertificate),
                null
                );
            // The server name must match the name on the server certificate.
            try
            {
                sslStream.AuthenticateAsClient(serverName);
            }
            catch (AuthenticationException e)
            {
                Console.WriteLine("Exception: {0}", e.Message);
                if (e.InnerException != null)
                {
                    Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                }
                Console.WriteLine("Authentication failed - closing the connection.");
                client.Close();
                return;
            }

            // Encode a test message into a byte array.
            // Signal the end of the message using the "$".
            byte[] messsage = Encoding.UTF8.GetBytes(inputMessage + "$");
            // Send hello message to the server. 
            sslStream.Write(messsage);
            sslStream.Flush();

            // Read message from the server.
            string serverMessage = ReadMessage(sslStream);
            Console.WriteLine("Server says: {0}", serverMessage.Substring(0, serverMessage.IndexOf("$")));


            // Close the client connection.
            client.Close();
            Console.WriteLine("Client closed.");
            Console.WriteLine();
        }

        private static string ReadMessage(SslStream sslStream)
        {
            // Read the message sent by the server.
            // The end of the message is signaled using the "$" marker
            byte[] buffer = new byte[2048];
            StringBuilder messageData = new StringBuilder();
            int bytes = -1;

            do
            {
                bytes = sslStream.Read(buffer, 0, buffer.Length);

                Decoder decoder = Encoding.UTF8.GetDecoder();
                char[] chars = new char[decoder.GetCharCount(buffer,0,bytes)];
                decoder.GetChars(buffer, 0, bytes, chars, 0);
                messageData.Append(chars);

                if (messageData.ToString().IndexOf("$") != -1)
                {
                    break;
                }
            } while (bytes != 0);

            return messageData.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {            
            string inputMessage = string.Empty;

            do
            {
                Console.Write("Clients says: ");
                inputMessage = Console.ReadLine();
                SslTcpClient.RunClient("192.168.0.12", "XYZ Company", inputMessage);
            } while (inputMessage.ToLower() != "exit");
            
            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        }
    }


posted by 따시쿵
prev 1 2 3 4 5 6 7 ··· 12 next