728x90

C# 에서 새로운 창을 만들어서 새로운 창으로 값을 전달하는 걸 만들고 있었다.

그런데 실행을 하면 "개체 참조가 개체의 인스턴스로 설정되지 않았습니다" 라는 메시지를 뿌려준다.


검색을 해보니까

값이 null 일 경우에 이런 메시지가 나온다고 한다.


그래서 null 값으로 넘어가는 것이 있나 확인을 해봐도 결과는 동일하다.


결국 알고보니 DB에서 조회하는 필드에 없는 필드값을 화면에 적어둔 것이 문제였다.


기존 자료를 복사하여 붙여넣기 하고서 필요한 칼럼만 가져오기 위해서 DB Select 칼럼은 지웠는데 화면에 표시하는 칼럼 이름을 미처 삭제를 못하면서 발생한 현상이었다.


이것 원인 찾으라고 한참을 헤매었다.


소스코드를 그대로 복사하여 붙여넣기를 할 경우

private void searchBox_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        btnSearch_Click(sender, e);
    }
}


기능이 동작하지 않는다면???


searchBox_KeyDown 에서 마우스 우클릭을 하고, 모든 참조찾기(Shift + F12) 키를 눌러본다.


this.searchBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.searchBox_KeyDown);
가 검색되지 않는다면 이벤트 핸들러 등록이 안되어 있다는 것이다.

이 경우에는 이벤트 핸들러를 생성해주어야 한다.


ContextMenu 에서 메뉴 항목을 정리한다고 sub 메뉴로 이동시킬 때에도 연결되었던 이벤트핸들러가 연결이 사라지더라.




블로그 이미지

Link2Me

,
728x90

지정된 형식에 따라 개체의 값을 문자열로 변환하여 다른 문자열에 삽입한다.

string.Format("{0};{1};{2};{3};{4};{5}",textBox1.Text.Trim(), textBox2.Text.Trim(), textBox3.Text.Trim(), textBox4.Text.Trim(), textBox5.Text.Trim(), textBox6.Text.Trim());


숫자형식 포맷팅을 이용하면 숫자로 이루어진 문자열을 다양한 형태로 출력 할 수 있다.

기본적으로 이 포맷팅은 System. String.Format 매서드에 기반하여 적용된다.


형식지정자

종류

예제코드

출력결과

C / c

통화
Currency

 Response.Write(string.Format("{0:C}", 2.5));

₩3

 Response.Write(string.Format("{0:C}", -3.5));

-₩4

D / d

10진법
Decimal

 Response.Write(string.Format("{0:D}", 00035));

35

E / e

과학적지수
Scientific

 Response.Write(string.Format("{0:E}", 342));

3.420000E+02

F / f

고정 소수점
Fixed-point

 Response.Write(string.Format("{0:F2}", 35.22));

35.22

 Response.Write(string.Format("{0:F0}", 35.22));

35

G / g

일반
General

 Response.Write(string.Format("{0:G}", 123456));

123456

N / n

숫자
Number

 Response.Write(string.Format("{0:N}", 25000000));

25,000,000.00

P / p

백분율
Percentage

 Response.Write(string.Format("{0:P}", .21548));

21.55%

 Response.Write(string.Format("{0:P1}", .112345));

11.2%

X / x

16진법
Hexadecimal

 Response.Write(string.Format("{0:X}", 250));

FA

 Response.Write(string.Format("{0:X}", 0xffff));

FFFF


출처 : http://www.dreamy.pe.kr/zbxe/CodeClip/157656


http://ryuschool.tistory.com/entry/C-%EB%AC%B8%EC%9E%90%EC%97%B4-StringFormat


이곳에 가면 String.Format 에 대한 샘플이 있으니 참고하면 된다.

http://www.csharp-examples.net/string-format-double/


블로그 이미지

Link2Me

,
728x90

C# dataGridView 에 엑셀파일을 읽어들일 때 엑셀 파일의 형식인지를 체크하여 엑셀파일이 아닌 것은 사전에 차단하는 기능이 추가된 엑셀 읽어들이는 코드이다.


엑셀 파일 형식 검사하는 코드는 인터넷 서칭하다가 발견했는데 그분의 블로그가 당장은 생각나지 않는다.

형식검사하는 것은 간단하게 파악할 수가 있다.

HEX View 파일(http://link2me.tistory.com/807)을 설치해서 파일을 Drag & Drop 하면 헤더부분에서 엑셀파일인지 아닌지를 판별할 수가 있다.

임의로 다른 파일을 엑셀로 확장자를 변경해도 실제는 엑셀 파일이 아니므로 걸러낼 수가 있다.


형식검사하는 걸 응용하면 Encoding 검사할 수도 있다.


private void btnExcelRead_Click(object sender, EventArgs e)
{
    try
    {
        // 파일 선택창 객체를 생성
        using (OpenFileDialog dlg = new OpenFileDialog())
        {
            dlg.Filter = "Excel Files(2007이상)|*.xlsx|Excel Files(97~2003)|*.xls";
            dlg.InitialDirectory = @"C:\test\";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                ImportExcelData_Read(dlg.FileName, dataGridView1); // dataGridView에 데이터를 세팅 메서드 호출
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }           
}

public static DataSet ImportExcelData_Read(string fileName, DataGridView dgv)
{
    // 엑셀 문서 읽어서 dataGridView 에 출력하기
    string connectionString = string.Empty;

    if (File.Exists(fileName))
    {
        int ExcelType = ExcelFileType(fileName);  // 엑셀파일 형식 검사
        switch (ExcelType)
        {
            case (-2): throw new Exception(fileName + "의 형식검사중 오류가 발생하였습니다.");
            case (-1): throw new Exception(fileName + "은 엑셀 파일형식이 아닙니다.");
            case (0):
                connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0};Extended Properties='Excel 8.0';", fileName);
                break;
            case (1):
                connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0; Data Source={0};Extended Properties='Excel 12.0';", fileName);
                break;
        }
    }

    DataSet DS = new DataSet();

    string strQuery = "SELECT * FROM [Sheet1$]";
    OleDbConnection oleDBConn = new OleDbConnection(connectionString);
    oleDBConn.Open();

    OleDbCommand oleCmd = new OleDbCommand(strQuery, oleDBConn);
    OleDbDataAdapter dataAdapter = new OleDbDataAdapter(oleCmd);

    DataTable dataTable = new DataTable();
    dataAdapter.Fill(dataTable);
    DS.Tables.Add(dataTable);

    dgv.DataSource = DS.Tables[0].DefaultView;

    // 데이터에 맞게 칼럼 사이즈 조정하기
    for (int i = 0; i < dgv.Columns.Count; i++)
    {
        dgv.AutoResizeColumn(i, DataGridViewAutoSizeColumnMode.AllCells);
    }
    dgv.AllowUserToAddRows = false;  // 빈레코드 표시 안하기
    dgv.AlternatingRowsDefaultCellStyle.BackColor = Color.AliceBlue;
    //dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; // 화면크기에 맞춰 채우기

    dataTable.Dispose();
    dataAdapter.Dispose();
    oleCmd.Dispose();

    oleDBConn.Close();
    oleDBConn.Dispose();

    return DS;
}

#region 엑셀파일 형식
public static int ExcelFileType(string XlsFile)
{
    byte[,] ExcelHeader = {
        { 0xD0, 0xCF, 0x11, 0xE0, 0xA1 }, // XLS  File Header
        { 0x50, 0x4B, 0x03, 0x04, 0x14 }  // XLSX File Header
    };

    // result -2=error, -1=not excel , 0=xls , 1=xlsx
    int result = -1;

    FileInfo FI = new FileInfo(XlsFile);
    FileStream fs = FI.Open(FileMode.Open);

    try
    {
        byte[] buffer = new byte[5];
        fs.Read(buffer, 0, 5);
        for (int i = 0; i < 2; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                if (buffer[j] != ExcelHeader[i, j]) break;
                else if (j == 4) result = i;
            }
            if (result >= 0) break;
        }
    }
    catch
    {
        result = (-2);
    }
    finally
    {
        fs.Close();
    }
    return result;
}
#endregion



블로그 이미지

Link2Me

,
728x90

C# 에서 dataGridView 내용을 CSV 파일로 내보내기하는 코드이다.

CSV 파일은 텍스트 파일 내보내기와 동일하다.

기존 파일이 존재하는데 덮어쓰기 시도하면 덮어쓰기 된다.


private void btnCSV_Save_Click(object sender, EventArgs e)
{
    using (SaveFileDialog dlg = new SaveFileDialog())
    {
        dlg.Filter = "csv (*.csv) | *.csv";
        if (dlg.ShowDialog() == DialogResult.OK)
        {
            this.Save_Csv(dlg.FileName, dataGridView1); // dataGridView에 데이터를 세팅하는 메서드를 호출
        }
    }
}


/// <summary>
/// dataGridView 데이터를 CSV 로 파일 내보내기
/// </summary>
private void Save_Csv(string fileName, DataGridView dgv, bool header)
{
    string delimiter = ";";  // 구분자
    FileStream fs = new FileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.Write);
    StreamWriter csvExport = new StreamWriter(fs, System.Text.Encoding.UTF8);

    if (dgv.Rows.Count == 0) return;

    // 헤더정보 출력
    if (header)
    {
        for (int i = 0; i < dgv.Columns.Count; i++)
        {
            csvExport.Write(dgv.Columns[i].HeaderText);
            if (i != dgv.Columns.Count - 1)
            {
                csvExport.Write(delimiter);
            }
        }
    }

    csvExport.Write(csvExport.NewLine); // add new line

    // 데이터 출력
    foreach (DataGridViewRow row in dgv.Rows)
    {
        if (!row.IsNewRow)
        {
            for (int i = 0; i < dgv.Columns.Count; i++)
            {
                csvExport.Write(row.Cells[i].Value);
                if (i != dgv.Columns.Count - 1)
                {
                    csvExport.Write(delimiter);
                }
            }
            csvExport.Write(csvExport.NewLine); // write new line
        }
    }
   
    csvExport.Flush(); // flush from the buffers.
    csvExport.Close();
    fs.Close();
    MessageBox.Show("CSV파일 저장 완료!");
}





블로그 이미지

Link2Me

,
728x90

C# 에서 MySQL 에 접속하여 게시물 갯수를 구하는 간단한 코드이다.


먼저 상시적으로 사용되는 것은 Class 상위에 둔다.

C# 에서 MySQL 을 접속시 localhost 의미하는게 뭔지 모르는 개발 입문자들이 많은거 같다.

localhost = 서버와 클라이언트(C#으로 만든 프로그램)가 같은 곳에 존재

호스팅을 이용할 경우에는 클라이언트와 서버의 물리적인 장소가 서로 다르다. 이 경우에는 서버의 실제 접속 IP주소를 적어줘야 한다.


MySQL 에서는 외부에서 접속할 수 있는 사용자권한을 부여해야 한다. 이 사항은 http://link2me.tistory.com/431 게시글을 읽어보면 이해가 될 것이다.


이 두가지 사항을 알고 이제 코드를 작성해보자.


MySQL 접속하여 결과를 얻는 방법은 여러가지가 있다.

여기서는 Select count(*) FROM 테이블명 WHERE 조건; 인 단순 예제를 작성했다.

object result = cmd.ExecuteScalar();

ExecuteScalar() 메서드는 쿼리를 실행하고 쿼리에서 반환된 결과 집합의 첫번째 행의 첫번째 열을 반환한다.

추가 열이나 행은 무시한다. 집계함수(SUM, AVG, MAX, MIN) 를 이용한 결과를 구할 때 사용된다.

ConnectionString은 암호화를 하여 저장하고 실제 사용할 때만 복호화를 할 수 있으면 제일 좋다.


=== 소스코드 ===

string ConnectionString = "SERVER=localhost;DATABASE=dbname;UID=dbuserid;PASSWORD=dbpassword;";
MySqlConnection myConn;

private int totalcnt()
{
    int cnt = 0;
    try
    {
        myConn = new MySqlConnection(ConnectionString);
        if (myConn.State == ConnectionState.Closed)
        {
            myConn.Open();
        }
        string strqry = "select count(uid) from data";
        MySqlCommand cmd = new MySqlCommand(strqry, myConn);
        cnt = int.Parse(cmd.ExecuteScalar().ToString());
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        this.myConn.Close();
    }
    return cnt;
}


본 게시글은 MySQL 접속을 알고 싶은 초보자를 위해 작성해봤습니다.



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

C# MySQL 데이터를 ListView 에 Add 하는 방법 (1)  (2) 2015.12.29
C# DataSet  (6) 2015.12.20
C# MySQL 쿼리문과 연동 처리  (0) 2015.09.12
C# 콤보박스(comboBox) 와 SQL 연동  (0) 2015.09.10
C# 과 MySQL 연동  (0) 2015.08.29
블로그 이미지

Link2Me

,
728x90

C# 에서 자식창을 띄울때 창의 마지막 크기와 위치를 저장하고 싶을 때


먼저, 솔루션 탐색기에서 Properties 를 선택하고 Settings.settings 를 더블 클릭한다.



아래 그림처럼 이름과 형식을 설정해준다.



이제 이벤트를 생성하여 코드를 추가한다.


private void WBrowser_FormClosing(object sender, FormClosingEventArgs e)
{
    Properties.Settings.Default.FormSize = this.Size;
    Properties.Settings.Default.Location = this.Location;
    Properties.Settings.Default.Save();
}


private void WBrowser_Load(object sender, EventArgs e)
{
    this.Size = Properties.Settings.Default.FormSize;
    this.Location = Properties.Settings.Default.Location;
}



창의 최소 사이즈는 속성에서 설정해준다.




블로그 이미지

Link2Me

,
728x90



로그인 ID를 매번 입력해야 하는 번거로움을 없애는 방법이 뭘까?


Registry 에 정보를 저장하고 읽어오는 방법도 있는거 같은데 정보를 저장할때 관리자 권한으로 실행을 해야 저장이 가능한거 같다.


현재 상태의 설정값(로그인 ID, 비밀번호 등)을 저장하여 다음번 Load 시 불러다 이용하려고 할 경우

Properties.Settings 를 이용한다.


먼저, 솔루션 탐색기에서 Properties 를 선택하고 Settings.settings 를 더블 클릭한다.




이름 적는 곳에 기록할 이름을 적어준다. 그리고 필요하면 값부분에 적어준다.



이제 Load 될 때와 Form 이 Closing 될 때 코드를 추가해준다.


private void frmLogin_Load(object sender, EventArgs e)
{
    txtID.Text = Properties.Settings.Default.LoginIDSave;
}

private void frmLogin_FormClosing(object sender, FormClosingEventArgs e)
{
    if (!CK)
    {
        Application.Exit();
    }
    else
    {
        Properties.Settings.Default.LoginIDSave = txtID.Text;
        Properties.Settings.Default.Save();
    }
}


최초 로그인할 때는 아이디 입력창이 빈 상태이겠지만 프로그램을 한번 실행하고 나서 다음에 로그인하면 아래 그림처럼 ID 정보가 자동으로 불러와 있다.



이 정보는 C:\Users\사용자\AppData 하위의 해당 App 폴더에 값이 저장된다.




아이디 저장을 체크한 경우에 저장되도록 하고자 한다면,  Form_Closing 되는 곳에서는 삭제하고 로그인 OK 되는 이벤트에서 값을 저장해준다.


private void btnOK_Click(object sender, EventArgs e)
{
    if (this.txtID.Text == "")
    {
        MessageBox.Show("로그인 아이디를 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.txtID.Focus();
    }
    else if (this.txtPwd.Text == "")
    {
        MessageBox.Show("로그인 비밀번호를 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.txtPwd.Focus();
    }
    else
    {
        if (IDSave.Checked) // 로그인 OK 버튼 실행할 때 저장
        {
            Properties.Settings.Default.LoginIDSave = txtID.Text;
            Properties.Settings.Default.Save();
        }
        mySqlLogin();
    }
}



아래 코드는 윈도우 운영체제 부팅하면서 입력창 나오는 곳에서 입력한 ID 정보를 얻어내는 방법이다.


string userName = null;
using (System.Security.Principal.WindowsIdentity wi = System.Security.Principal.WindowsIdentity.GetCurrent())
{
    userName = wi.Name;
}


MessageBox.Show(userName);


블로그 이미지

Link2Me

,
728x90

C# 에서 %를 구하는 함수다.

구글링하면 온갖 함수들이 나오는데 시간낭비다.

제공되는 Math.Round 함수를 이용하면 한줄이면 된다.


private double GetPercentage(double value, double total, int decimalplaces)
{
    return System.Math.Round(value * 100 / total, decimalplaces) ;
}


사용예제

string.Format("입력 : {0} (전체의 {1}%)", cnt, GetPercentage(cnt,DBtotalcnt(),2));

블로그 이미지

Link2Me

,
728x90

MP3 파일 헤더에 포함된 태그 정보를 가져오는 함수이다.

구글링을 통해서 얻은 자료를 가지고 쉽게 원하는 정보를 얻기 위해서 함수화를 했다.


사용법

using (OpenFileDialog dlgOpen = new OpenFileDialog())
{
    dlgOpen.Filter = "MP3 File|*.mp3";
    dlgOpen.Title = "Select Audio File";
    //dlgOpen.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);

    if (dlgOpen.ShowDialog() == DialogResult.OK)
    {
        // listView 등에 원하는 형태로 출력하여 사용
        MessageBox.Show("제목 : " + MP3TAG_Split(dlgOpen.FileName, 0));
    }
}



함수
/// <summary>
/// MP3 파일 헤더에 포함된 태그를 추출하여 타이틀, 가수, 앨범, 연도, 코멘ㅌ, 장르 정보를 가져옵니다
/// </summary>
/// <param name="filePath">파일경로를 포함한 MP3파일명</param>
/// <param name="index">추출할 인덱스</param>
/// <returns>추출된 문자열</returns>
public string MP3TAG_Split(string filePath, int index)
{
    string _parseString = ";";  // MP3_TAG 의 구분자
    string _body = MP3TAG_Read(filePath);
    if (_body != string.Empty)
    {
        return _body.Split(new string[] { _parseString }, StringSplitOptions.None)[index];
    }
    else
    {
        return string.Empty;
    }
}

public string MP3TAG_Read(string filePath)
{
    using (FileStream fs = File.OpenRead(filePath))
    {
        if (fs.Length >= 128)
        {
            MP3ID3Tag tag = new MP3ID3Tag(); // 클래스형인 tag 객체 초기화
            fs.Seek(-128, SeekOrigin.End);
            fs.Read(tag.TAGID, 0, tag.TAGID.Length);
            fs.Read(tag.Title, 0, tag.Title.Length);
            fs.Read(tag.Artist, 0, tag.Artist.Length);
            fs.Read(tag.Album, 0, tag.Album.Length);
            fs.Read(tag.Year, 0, tag.Year.Length);
            fs.Read(tag.Comment, 0, tag.Comment.Length);
            fs.Read(tag.Genre, 0, tag.Genre.Length);
            string theTAGID = Encoding.Default.GetString(tag.TAGID);

            if (theTAGID.Equals("TAG"))
            {
                string Title = Encoding.Default.GetString(tag.Title);
                string Artist = Encoding.Default.GetString(tag.Artist);
                string Album = Encoding.Default.GetString(tag.Album);
                string Year = Encoding.Default.GetString(tag.Year);
                string Comment = Encoding.Default.GetString(tag.Comment);
                string Genre = Encoding.Default.GetString(tag.Genre);

                return string.Format("{0};{1};{2};{3};{4};{5}",Title,Artist,Album,Year,Comment,Genre);
            }
            else
            {
                return string.Empty;
            }
        }
        else
        {
            return string.Empty;
        }
    }
}



// MP3ID3Tag 의 클래스

class MP3ID3Tag
{
    public byte[] TAGID = new byte[3];      //  3
    public byte[] Title = new byte[30];     //  30
    public byte[] Artist = new byte[30];    //  30
    public byte[] Album = new byte[30];     //  30
    public byte[] Year = new byte[4];       //  4
    public byte[] Comment = new byte[30];   //  30
    public byte[] Genre = new byte[1];      //  1
}



블로그 이미지

Link2Me

,
728x90

C#에서 파일을 다중으로 선택하여 가져오기를 하는 코드이다.


MP3 파일을 다중으로 선택하여 가져오기를 할 경우에 적용해본 코드이다.


private void MP3File_Open()
{
    using (OpenFileDialog dlgOpen = new OpenFileDialog())
    {
        dlgOpen.Filter = "MP3 File|*.mp3";
        dlgOpen.Title = "Select Audio File";
        dlgOpen.Multiselect = true; // 파일 다중 선택
        //dlgOpen.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
        if (dlgOpen.ShowDialog() == DialogResult.OK)
        {
            for (int i = 0; i < dlgOpen.FileNames.Length; i++)
            {
                FileOpen_ListView(dlgOpen.FileNames[i], listView1);
            }
        }
    }
}


private void FileOpen_ListView(string fileName, ListView LV)
{
    if (File.Exists(fileName))
    {
        if (Path.GetExtension(fileName).ToLower() == ".mp3")
        {
            Load_MP3(fileName, LV);
        }     
    }
}



for 문 대신에 foreach 문을 사용하면 .....

private void MP3File_Open()
{
    using (OpenFileDialog dlgOpen = new OpenFileDialog())
    {
        dlgOpen.Filter = "MP3 File|*.mp3";
        dlgOpen.Title = "Select Audio File";
        dlgOpen.Multiselect = true; // 파일 다중 선택
        if (dlgOpen.ShowDialog() == DialogResult.OK)
        {
            foreach (string file in dlgOpen.FileNames)
            {
                try
                {
                    FileOpen_ListView(file, listView1);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
    }
}



블로그 이미지

Link2Me

,
728x90

메인폼(MainForm)에서 자식폼을 실행하고 난 후 자식폼의 종료버튼을 눌러도 종료되지 않도록 처리하는게 필요하여 적어둔다.




메인폼에서 자식폼을 띄우는 이벤트

private void pictureBoxOpen_Click(object sender, EventArgs e)
{
    foreach (Form openForm in Application.OpenForms)
    {
        if (openForm.Name == "MP3List") //폼 중복 열기 방지
        {
            if (openForm.WindowState == FormWindowState.Minimized)
            {
                openForm.WindowState = FormWindowState.Normal;
            }
            openForm.Activate();
            return;
        }
    }

    MP3List frm2 = new MP3List();
    frm2.TextSendEvent += new MP3List.MP3List_EventHandler(frm2_getTextEvent);
    frm2.Show();
}



자식폼에서 종료버튼을 클릭하면 종료되지 않고 윈도우 상태가 Minimized 되도록 처리하는 방법

private void MP3List_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        e.Cancel = true;
        this.WindowState = FormWindowState.Minimized;
    }
}


'C# > 기능 활용' 카테고리의 다른 글

Inno Setup 을 이용한 설치 프로그램 만들기  (2) 2015.12.27
C# MP3 파일 헤더정보 추출하는 함수  (0) 2015.12.02
C# DLL 만들기  (0) 2015.11.14
C# 프로그램 사용기한 체크  (0) 2015.10.23
C# Get Mac Address  (0) 2015.10.12
블로그 이미지

Link2Me

,
728x90

C# 에서 폼간에 데이터를 전송한다는 의미를 정리해두려고 한다.

몇번의 수정을 하고 나서 이제는 거의 완벽하게 이해가 된 자료로 정리가 된 거 같다.

물론 실습으로 코딩을 하면서 막히면 자료를 보고 또 보면서 이 Properties 는 막힘없이 사용할 수 있게 되었다.


먼저 https://www.youtube.com/watch?v=PI3ad-TebP0

이 유투브 동영상을 보면 폼간에 데이터 전송하는 것이 나온다.


먼저 Form1 과 Form2 를 생성하고 UI를 작성해보자.


 


이제 F7키를 눌러서 코드를 살펴보자.



같은 Namespace 인데 class 이름은 Form1 과 Form2 로 서로 다르다.

C# 에서는 클래스가 다르면 원칙적으로 데이터에 접근할 수가 없다.

어느 클래스에서든지 접근이 가능하게 하려면 public 을 앞에 붙여줘야 한다.


속성(Properties)는 클래스의 인스턴스나 클래스 안의 데이터를 나타내는 하나의 멤버이다.

속성을 선언하는 형식은

데이터타입 속성이름

{

    get { return this.변수; }

    set { this.변수 = value; }

}


먼저, Form1 에서 Form2 를 호출하기 위한 코드

private void button1_Click(object sender, EventArgs e)
// Form1 에서 Form2 로 값을 전달하기 위한 이벤트 생성   
    Form2 frm2 = new Form2(); // Form2형 frm2 인스턴스화(객체 생성)
    frm2.ShowDialog();
}


이 코드는 Form2 창만 띄우는 것만 가능하지, 값을 전달하는 코드는 없다.

Form1의 textBox1 에서 입력한 값을 Form2 로 전달한다는 것은

Form2 에서 Form1의 값을 받아야 한다는 의미이다.



=== Form2 코드 ===

private string Form2_value;
public string Passvalue
{
    get { return this.Form2_value; }
    set { this.Form2_value = value; }  // 다른폼(Form1)에서 전달받은 값을 쓰기
}

private void Form2_Load(object sender, EventArgs e)
{
    textBox1.Text =
Passvalue; // 다른폼(Form1)에서 전달받은 값을 변수에 저장
}


=== Form1 코드 ===

private void button1_Click(object sender, EventArgs e)
{   // Form1 에서 Form2 로 값을 전달하기 위한 이벤트 생성
    if (textBox1.Text.Length == 0)
    {
         MessageBox.Show("값이 입력되지 않았습니다");
         return;
    }

    Form2 frm2 = new Form2(); // Form2형 frm2 인스턴스화(객체 생성)
    frm2.Passvalue = textBox1.Text;  // 전달자(Passvalue)를 통해서 Form2 로 전달
    frm2.ShowDialog();
}




이제 Form2 에서 입력한 값을 Form1 으로 전달하기 위한 코드를 추가해보자.

=== Form2 코드 ===

private string Form2_value;
public string Passvalue
{
    get { return this.Form2_value; } // Form2에서 얻은(get) 값을 다른폼(Form1)으로 전달 목적
    set { this.Form2_value = value; }  // 다른폼(Form1)에서 전달받은 값을 쓰기
}

private void button1_Click(object sender, EventArgs e)
{

    if (textBox2.Text == string.Empty)
    {
        MessageBox.Show("textBox2에 값이 입력되지 않았습니다");
        return;
    }

    Passvalue = textBox2.Text; // Form1 으로 값을 전달하기 위해
    this.Hide();
}


=== Form1 코드 ===

private void button1_Click(object sender, EventArgs e)
{   // Form1 에서 Form2 로 값을 전달하기 위한 이벤트 생성

    if (textBox1.Text.Length == 0)
    {
         MessageBox.Show("값이 입력되지 않았습니다");
         return;
    }

    Form2 frm2 = new Form2(); // Form2형 frm2 인스턴스화(객체 생성)
    frm2.Passvalue = textBox1.Text; // 전달자(Passvalue)를 통해서 Form2 로 전달
    frm2.ShowDialog();

    textBox2.Text = frm2.Passvalue; // 전달자(Passvalue)를 통해서 전달받은 값
}


테스트를 해보니 이런 방식은

Form2 를 띄우고 닫으면서 값을 전달하는 방식인거 같다.

frm2.ShowDialog(); 대신에 frm2.Show(); 로 대체하고 테스트를 해보니까

Form1 으로 다시 값이 반환되지 않는다.


아래는 테스트에 사용된 소스코드이다.


Properties.zip





기존의 속성 선언시 static 키워드를 붙여주면 어떤 변화가 생길까?

클래스의 인스턴스를  생성할 필요없이 직접 접근이 가능해진다.

정적(static)필드로는 모든 클래스의 인스턴스에 의해 공유된다는 점이 가장 큰 차이점이다.

정적 변수는 오직 하나만 존재한다.

인스턴스 변수(비정적 변수)는 인스턴스화(메모리를 할당)할 때마다 생성된다.


this.Form2_value 를 사용할 수 없게 에러가 표시된다. 즉, this 인 Form2 에서만 사용되는 범주를 벗어난다

=== Form2 코드 ===

private static string Form2_value;
public static string Passvalue
{
    get { return Form2_value; } // Form2에서 얻은(get) 값을 다른폼(Form1)으로 전달 목적
    set { Form2_value = value; }  // 다른폼(Form1)에서 전달받은 값을 쓰기
}


에러가 생기는 부분을 수정해줘야 한다.

객체 생성에 영향을 받지 않으므로 frm2 대신에 Form2 로 수정해준다.


=== Form1 코드 ===

private void button1_Click(object sender, EventArgs e)
{

    if (textBox1.Text.Length == 0)
    {
         MessageBox.Show("값이 입력되지 않았습니다");
         return;
    }
   

    Form2 frm2 = new Form2(); // Form2형 frm2 인스턴스화(객체 생성)
    Form2.Passvalue = textBox1.Text; // 전달자(Passvalue)를 통해서 Form2 로 전달
    frm2.ShowDialog();

    textBox2.Text = Form2.Passvalue; // 전달자(Passvalue)를 통해서 전달받은 값
}




그런데

private static string Form2_value;
public static string Passvalue
{
    get { return Form2_value; } // Form2에서 얻은(get) 값을 다른폼(Form1)으로 전달 목적
    set { Form2_value = value; }  // 다른폼(Form1)에서 전달받은 값을 쓰기
}

위 코드를

public static string Passvalue { get; set; }

* 참조 : prop 을 치고 + tab키를 누르면 자동으로 코드가 만들어진다.


한줄로 변경하면 어떤 변화가 생길까?

코드도 간단해지만, Passvalue 는 전달자 역할만 하면서 어떤 값을 대입할지 고민하지 않아도 된다.


=== Form2 코드 ===

public static string Passvalue { get; set; }  // 자동 구현 Properties
private void Form2_Load(object sender, EventArgs e)
{
    textBox1.Text = Passvalue; // 다른폼(Form1)에서 전달받은 값을 변수에 저장
}

private void button1_Click(object sender, EventArgs e)
{
    Passvalue = textBox2.Text; // Form1 으로 값을 전달하기 위해
    this.Hide();
}


=== Form1 코드 ===

private void button1_Click(object sender, EventArgs e)
{
    Form2 frm2 = new Form2(); // Form2형 frm2 인스턴스화(객체 생성)
    Form2.Passvalue = textBox1.Text; // 전달자(Passvalue)를 통해서 Form2 로 전달
    frm2.ShowDialog();

    textBox2.Text = Form2.Passvalue; // 전달자(Passvalue)를 통해서 Form2 값을 받음
}


Properties2.zip


static 을 추가하지 않으면 Form2 객체 생성을 통해서 값이 전달된다는 차이점만 있다.


결론은 전달받을 Form 에 Properties 를 추가한다는 것만 기억하자...





공통으로 사용할 것이라면 별도의 클래스를 따로 만들어서 Properties 를 추가하는 게 좋다.

prop 를 누르고 탭탭을 누르면 Properties 가 자동으로 완성시킬 수 있는 형태가 나온다.



블로그 이미지

Link2Me

,
728x90

자식폼에서 메인폼으로 값을 전달하는 방법으로
public 을 선언하여 넘겨주는 방법만 사용했었는데 이번에 검색해서 좋은 정보를 알게되었다.

배운지도 얼마 안되고 독학을 하다보니 C# 기능을 제대로 몰라서 애로사항이 많다.

몇번 더 적용해보면 확실하게 내것이 될 수 있을 거 같다.

(작성일자 : 2015.11.29) -- delegate 를 제대로 이해하지 못한 상태에서 작성한 자료


목적1 : 자식폼(Form2) 에서 메인폼으로 데이터 전달


=== 자식폼에서 설정하는 것들 =====
public delegate void Form2_EventHandler(string data); // string 을 반환값으로 같은 대리자를 선언
public event Form2_EventHandler TextSendEvent// 대리자 타입의 이벤트 처리기를 설정

// 클릭하여 실제 전달되는 값
TextSendEvent(dlgOpen.FileName.ToString()); // 스트링값을 메인폼에게 보내줌


=== 메인폼에서 설정하는 것들 ===
// 자식폼(Form2)를 띄우는 이벤트
private void pictureBoxOpen_Click(object sender, EventArgs e)
{
    foreach (Form openForm in Application.OpenForms)
    {
        if (openForm.Name == "Form2") //폼 중복 열기 방지
        {
            openForm.Activate();
            return;
        }
    }

    Form2 frm2 = new Form2();

    // 자식폼이 가지고 있는 TextSendEvent 이벤트 처리기에 frm2_getTextEvent 이벤트 연결

    frm2.TextSendEvent += new Form2.Form2_EventHandler(frm2_getTextEvent);
    frm2.Show();  // 자식폼이 활성화된  상태에서 값을 전달받기 위해서
}

void frm2_getTextEvent(string text)
{
    // 값을 넘겨 받아서 실제 처리할 함수
    CurrentData = text; // Form2 에서 넘겨받는 값
}


참고한 자료는 http://blog.naver.com/kjh258999/20043308380 이며, 테스트를 통해서 동작되는 걸 확인하면서 이름 변경을 해보면서 어떤 이름들이 변경되는지 확인하였다.

그래서 좀 더 이해가 되도록 이름을 변경했고, 색상으로 표시를 했다.

다른 블로그(http://notull.tistory.com/entry/C-%ED%8F%BC%EA%B0%84-%EA%B0%92%EC%A0%84%EB%8B%AC-Event%EB%B0%9C%EC%83%9D)에도 예제 비슷하게 되어 있는데 설명은 없다.



목적2 : 메인폼에서 자식폼으로 데이터를 전송하는 방법


=== 메인폼에서 설정하는 것들 ===
// 자식폼(Form2)를 띄우는 이벤트
private void pictureBoxOpen_Click(object sender, EventArgs e)
{
    foreach (Form openForm in Application.OpenForms)
    {
        if (openForm.Name == "Form2") //폼 중복 열기 방지
        {
            openForm.Activate();
            return;
        }
    }

    Form2 frm2 = new Form2();

    frm2.Owner = this;  // 이 한줄을 추가해준다

    // 자식폼이 가지고 있는 TextSendEvent 이벤트 처리기에 frm2_getTextEvent 이벤트 연결

    frm2.TextSendEvent += new Form2.Form2_EventHandler(frm2_getTextEvent);
    frm2.Show();  // 자식폼이 활성화된  상태에서 값을 전달받기 위해서
}

void frm2_getTextEvent(string text)
{
    // 값을 넘겨 받아서 실제 처리할 함수
    CurrentData = text; // Form2 에서 넘겨받는 값
}



=== 자식폼에서 설정하는 것들 =====
public delegate void Form2_EventHandler(string data); // string 을 반환값으로 같은 대리자를 선언
public event Form2_EventHandler TextSendEvent// 대리자 타입의 이벤트 처리기를 설정

// 클릭하여 실제 전달되는 값
TextSendEvent(dlgOpen.FileName.ToString()); // 스트링값을 메인폼에게 보내줌


// 메인폼의 이름이 Form1 이라고 한다면

Form1 f1 = (Form1)this.Owner;

한줄을 추가해주고 나서, 값을 뿌릴 곳에다가 뿌려준다.

MessageBox.Show(f1.textBox1.Text);

textBox1 의 속성 중에서 Modifies 를 public 으로 반드시 변경해야 한다.

넘겨줄 값이 labelSubtitle1.Text 라서 아래 화면처럼 속성을 변경해줬다.



Form2 를 Load 하면서 메인폼의 값을 전달하는게 맞을거 같아서 Load 이벤트에 내용을 추가했다.

private void Form2_Load(object sender, EventArgs e)
{
    MainForm f1 = (MainForm)this.Owner;
    SearchBox.Text = System.IO.Path.GetFileNameWithoutExtension(f1.labelSubtitle1.Text);
    // Modifiers 를 public 으로 설정해줘야 된다.
}


블로그 이미지

Link2Me

,
728x90
파일명 변경은 System.IO.File.Move(oldname, newname);

파일명 복사는 System.IO.File.Copy(oldname, newname);


oldFileName 은 파일경로와 파일명이 포함된 문자열


private string FileCopy(string oldFileName)
{
    string filePath = Path.GetDirectoryName(oldFileName);  // 파일 경로
    string filename_without_ext = Path.GetFileNameWithoutExtension(oldFileName);  // 파일 이름
    string ext_only = Path.GetExtension(oldFileName);  // 파일 확장자
    string newFileName = filePath + "\\" + filename_without_ext + "_Temp" + ext_only;
    if (File.Exists(newFileName))  // 파일의 존재 유무 확인 : 파일이 존재하면
    {
        string message = string.Format("{0} 파일이 이미 있습니다. 바꾸시겠습니까?", Path.GetFileName(newFileName));
        DialogResult dialogResult = MessageBox.Show(message, "알림", MessageBoxButtons.YesNo);
        if (dialogResult == DialogResult.Yes)
        {
            File.Delete(newFileName);  // 존재하는 파일 삭제
            File.Copy(oldFileName, newFileName);
        }
        else
        {
            DialogResult changeResult = MessageBox.Show("다른 파일로 변경하시겠습니까?", "알림", MessageBoxButtons.YesNo);
            if (changeResult == DialogResult.Yes)
            {
                SaveAsFile(listView2);  // SaveDialog 를 이용한 파일 저장
            }
            else
            {
                MessageBox.Show("파일명 변경을 취소하셨습니다");
            }
            newFileName = string.Empty;  // SaveAsFile 함수에서 이미 파일명 변경했거나 저장 취소
        }
    }
    else  
// 파일의 존재하지 않으면   

   {
        File.Copy(oldFileName, newFileName);
    }
    return newFileName;
}

블로그 이미지

Link2Me

,

C# DLL 만들기

C#/기능 활용 2015. 11. 14. 00:00
728x90

DLL 이 외부로 공개할 수 있는 것은 클래스, 구조체, 열거형, 인터페이스 같은 타입인데 주로 클래스를 공개한다.


DLL 을 만들기 위한 절차

1. 비주얼 스튜디오 실행시킨 후 파일 - 새로 만들기 - 프로젝트를 실행한다.

클래스 라이브러리를 선택하고 파일 이름을 Link2Me 로 생성했다.


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

namespace Link2Me
{
    public class Class1
    {
    }
}

로 기본 파일이 생성된다.


2. 만들고자 하는 코드를 작성한다.

using System;
using System.IO;
using System.Net;

namespace Link2Me
{
    public class Logic
    {
        /// <summary>
        /// 문자열 원본에서 오른쪽에서 부터 추출한 갯수만큼 문자열을 가져옵니다.
        /// </summary>
        /// <param name="Text">문자열 원본</param>
        /// <param name="nLength">추출할 갯수</param>
        /// <returns>추출된 문자열</returns>
        public string RIGHT(string Text, int nLength)
        {
            string ConvertText = string.Empty;
            if (Text.Length < nLength)
            {
                nLength = Text.Length;
            }
            ConvertText = Text.Substring(Text.Length - nLength, nLength);
            return ConvertText;
        }

        /// 문자열 원본에서 왼쪽에서 부터 추출한 갯수만큼 문자열을 가져옵니다.
        /// </summary>
        /// <param name="Text">문자열 원본</param>
        /// <param name="nLength">추출할 갯수</param>
        /// <returns>추출된 문자열</returns>
        public string LEFT(string Text, int nLength)
        {
            string ConvertText = string.Empty;
            if (Text.Length < nLength)
            {
                nLength = Text.Length;
            }
            ConvertText = Text.Substring(0, nLength);
            return ConvertText;
        }

        /// <summary>
        /// 문자열 원본의 지정한 위치에서 부터 추출할 갯수 만큼 문자열을 가져옵니다.
        /// </summary>
        /// <param name="Text">문자열 원본</param>
        /// <param name="nStart">추출을 시작할 위치, 0부터 시작</param>
        /// <param name="nLength">추출된 문자열</param>
        /// <returns>추출된 문자열</returns>
        public string Mid(string Text, int nStart, int nLength)
        {
            string ConvertText;
            if (nStart < Text.Length)
            {
                if ((nStart + nLength) <= Text.Length)
                {
                    ConvertText = Text.Substring(nStart, nLength);
                }
                else
                {
                    ConvertText = Text.Substring(nStart);
                }
                return ConvertText;
            }
            else
            {
                Text = string.Empty;  // 시작점이 길이보다 길면 반환할 것이 없음
                return Text;
            }
        }

        /// <summary>
        /// 문자열이 숫자인지 검사하여 숫자이면 true 를 반환
        /// </summary>
        public bool isNumeric(string str)
        {
            double Num;
            bool isNum = double.TryParse(str, out Num);
            if (isNum)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 원하는 문자열을 잘라내는 함수입니다
        /// </summary>
        /// <param name="_body">원본 문자열</param>
        /// <param name="_parseString">Split할 구분자</param>
        /// <param name="index">Split으로 잘라진 배열의 숫자</param>
        public static string SSplit(string _body, string _parseString, int index)
        {
            // 엑셀 VBA 에서 사용하는 Split 함수
            string varTemp = _body.Split(new string[] { _parseString }, StringSplitOptions.None)[index];
            return varTemp;
        }

        /// <summary>
        /// 문자열에 한글이 포함되어 있는지 검사하여 포함되어 있으면 true 반환
        /// </summary>
        public bool isContainHangul(string s)
        {
            char[] charArr = s.ToCharArray();
            foreach (char c in charArr)
            {
                if (char.GetUnicodeCategory(c) == System.Globalization.UnicodeCategory.OtherLetter)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Public IP 주소를 문자열로 반환
        /// </summary>
        public static string GetRealIP()
        {
            string url = "http://www.findip.kr/";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";

            string resResult = string.Empty;
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                StreamReader readerPost = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8, true);
                resResult = readerPost.ReadToEnd();
            }

            if (resResult.IndexOf("내 아이피 주소(My IP Address) :") > 0)
            {
                int ingNO = resResult.IndexOf("내 아이피 주소(My IP Address) :");
                string varTemp = resResult.Substring(ingNO, 50);              
                string realip = SSplit(SSplit(varTemp, "내 아이피 주소(My IP Address) :", 1), "</h1>", 0).Trim();
                return realip;
            }
            return null;
        }
    }
}


3. 순수한 응용 프로그램 코드만 만드는 것이므로 Release 모드로 실행한다.

   



4. DLL 을 프로젝트 파일에 참조시키기








5. DLL 실행시키기

MessageBox.Show(Link2Me.Logic.GetRealIP());

로 테스트를 해봤다.

정상적으로 IP 정보를 잘 보여준다.

using Link2Me;

를 선언해서 사용해도 된다.


블로그 이미지

Link2Me

,
728x90

C#에서는 WinHttp.WinHttpRequest.5.1대신하여 HttpWebRequest를 사용할 수 있다.


WinHttp.WinHttpRequest.5.1 에서는

MessageBox.Show(http.GetAllResponseHeaders()); 를 이용하여 헤더 정보값을 확인할 수 있는데


HttpWebRequest 에서는 GetAllResponseHeaders() 함수가 없다.

이거 알아내느라고 개고생했다. 구글링, 네이버 검색해도 정보가 잘 검색되지 않는다.

결국 확인해보니 모든 헤더정보를 보여주는게 아니라, 해당 헤더정보를 읽어낼 수 있게 되어 있었다.

response.GetResponseHeader("Set-Cookie");


해당 헤더 정보를 읽어서 원하는 정보를 파싱(추출)하여 원하는 결과를 얻어냈다.


HttpWebRequest 클래스 : https://msdn.microsoft.com/ko-kr/library/system.net.httpwebrequest.aspx

using System.Net

using System.IO

두개의 Namespace 를 선언한다.


데이터를 byte 단위로 가져오기 때문에 StreamReader 가 필요하다.

POST 방식은 ID와 패스워드(PW)를 입력받아 입력받은 정보로 request 를 보내고, 응답받은 결과 메시지를 확인하여 필요한 정보를 추출하여 로그인 성공/실패 처리를 하도록 한다.


private string doLogin(string ID, string PW)
{
    string url = "http://www.abc.com/";
    string PostData = string.Format("r=home&a=login&referer=%2F%3F&__target=_parent&id={0}&pw={1}", ID.Trim(), PW.Trim());

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    request.Referer = "http://www.abc.com/?r=home&system=iframe.login&iframe=Y&referer=%2F%3F";
    request.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)";
    request.ContentType = "application/x-www-form-urlencoded";
    request.KeepAlive = true;
    request.AllowAutoRedirect = false;

    byte[] sendData = UTF8Encoding.UTF8.GetBytes(PostData);

    Stream dataStrem = request.GetRequestStream();
    dataStrem.Write(sendData, 0, sendData.Length);
    dataStrem.Close();

    string resResult = string.Empty;
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader readerPost = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8, true);   // Encoding.GetEncoding("EUC-KR")
    resResult = readerPost.ReadToEnd();
    //string cookie = response.GetResponseHeader("Set-Cookie"); // 쿠키정보 값을 확인하기 위해서
    //MessageBox.Show(cookie);
    //MessageBox.Show(resResult);
    readerPost.Close();
    response.Close();

    CK = false;
    if (resResult.IndexOf("패스워드가 일치하지 않습니다.") > 0)
    {
        MessageBox.Show("패스워드가 틀렸습니다", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.txtPwd.Focus();
    }
    else if (resResult.IndexOf("history.go(-1);//]]>") <= 0)  // 웹페이지 메세지가 없으면
    {
        if (response.GetResponseHeader("Set-Cookie").IndexOf("PHPSESSID=") != -1// 값이 없으면 - 1을 반환
        {
            CK = true;
            string strSessionID = SSplit(SSplit(response.GetResponseHeader("Set-Cookie"), "PHPSESSID=", 1), ";", 0);
            strID = txtID.Text;
            return strSessionID;
        }
    }
    return strID;  // 패스워드가 틀릴 경우에는 입력되는 ID값을 전달 받지 못하므로 null
}


// 엑셀 VBA 함수 Split 처럼 함수로 만들어서 사용

public static string SSplit(string _body, string _parseString, int index)
{
    string varTemp = _body.Split(new string[] { _parseString }, StringSplitOptions.None)[index];
    return varTemp;
}



ID가 null 인 경우에는 다음 단계 진행이 안되도록 처리


private void MainForm_Load(object sender, EventArgs e)
{
    frmLogin f2 = new frmLogin();  // 클래스 이름
    f2.ShowDialog();
    if (f2.getstrID == null)  // ID 입력값이 없으면 종료처리
    {
        Application.Exit();
    }
    else
    {
        this.Text = "접속 ID : " + f2.getstrID;
        this.WindowState = FormWindowState.Maximized;
        status_date(); 

        // 기본 처리할 내용 처리
    }
}


블로그 이미지

Link2Me

,
728x90

실행하면 웹브라우저 창이 뜨는 방식이다.

System.Diagnostics.Process.Start("http://subscene.com/");


웹브라우저 화면을 C# 프로그램 창 내부에 보이도록 하는 경우에는

//getCurrentBrowser().Navigate(adress);


private void searchTextBox_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        getCurrentBrowser().Navigate("http://endic.naver.com/search.nhn?sLn=kr&query=" + searchTextBox.Text);
    }
}



블로그 이미지

Link2Me

,
728x90

새로운 폼을 띄운 다음 그 폼에서 값을 받아서 처리해야 할 경우가 있다.

이때 폼을 띄울 때 처리해야 할 코드이다.


//폼 중복 열기 방지
foreach (Form openForm in Application.OpenForms)
{
    if (openForm.Name == "FindForm")
    {
        openForm.Activate();
        return;
    }
}

FindForm searchf = new FindForm();
searchf.StartPosition = FormStartPosition.Manual;
searchf.Location = new Point(100, 100);
if (searchf.ShowDialog() == DialogResult.OK)
{
    // 값을 넘겨 받아서 실제 처리할 함수
}


======= 값을 넘겨주는 Form 창 =======

public partial class FindForm : Form
{
    private int listView1_No;
    private int listView2_No;
    private int LV_No;

    public int LV1_No
    {
        get { return listView1_No; }
    }
    public int LV2_No
    {
        get { return listView2_No; }
    }
    public int SelectedViewNo
    {
        get { return LV_No; }
    }

    public FindForm()
    {
        InitializeComponent();
    }

    private void btnOK_Click(object sender, EventArgs e)
    {
        string Value1 = textBox1.Text;
        string Value2 = textBox2.Text;

        if (LV1.Checked)
        {
            LV_No = 1; // Value1
        }
        else
        {
            LV_No = 2; // Value2
        }

        int.TryParse(Value1, out listView1_No);
        if (Value1.Length == 0)
        {
            MessageBox.Show("Value1 의 값을 입력하지 않았습니다");
            return;
        }
        else if (listView1_No == 0)
        {
            MessageBox.Show("1 이상의 숫자를 입력해야 합니다");
            return;
        }

        int.TryParse(Value2, out listView2_No);
        if (Value2.Length == 0)
        {
            MessageBox.Show("Value2 의 값을 입력하지 않았습니다");
            return;
        }
        else if (listView2_No == 0)
        {
            MessageBox.Show("1 이상의 숫자를 입력해야 합니다");
            return;
        }
        DialogResult = DialogResult.OK;
    }

    private void btnCancel_Click(object sender, EventArgs e)
    {
        DialogResult = DialogResult.Cancel;
    }       

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        //숫자,백스페이스만 입력받는다.
        if (!(Char.IsDigit(e.KeyChar)) && e.KeyChar != 8) //8:백스페이스,45:마이너스,46:소수점
        {
            e.Handled = true;
        }
    }

    private void textBox2_KeyPress(object sender, KeyPressEventArgs e)
    {
        //숫자,백스페이스만 입력받는다.
        if (!(Char.IsDigit(e.KeyChar)) && e.KeyChar != 8) //8:백스페이스,45:마이너스,46:소수점
        {
            e.Handled = true;
        }
    }
}



블로그 이미지

Link2Me

,
728x90

C# 을 배우다보니 .NET 버전이 최소 4.0 은 되어야 동작하는 기능이 있다.

그래서 .NET 4.0 설치파일을 찾아서 첨부해둔다.

나중에 필요할 때가 있을 거 같아서다.


dotNetFx40_Full_setup.exe


블로그 이미지

Link2Me

,
728x90

private void GetDueday()
{   // 프로그램 사용기한 체크
    try
    {
        // DB에 저장된 사용기한 날짜 정보를 가져와서 오늘날짜와 비교
        string enddate = "201510/09"; // DB에서 가져온 날짜라고 가정
        DateTime today, endday;
        today = System.DateTime.Today;
        endday = System.DateTime.Parse(enddate);
        TimeSpan dayDiff;  // 시간의 차이를 구할 때 TimeSpan 사용
        dayDiff = endday - today;
        if (dayDiff.TotalDays > 0)
        {
            MessageBox.Show("사용기한이 " + dayDiff.TotalDays + " 일 남았습니다");
        }
        else if (dayDiff.TotalDays.Equals(0))
        {
            MessageBox.Show("오늘까지 사용할 수 있습니다");
        }
        else
        {
            MessageBox.Show("사용기한이 만료되어 더이상 사용할 수 없습니다");
            Application.Exit();
        }
    }
    catch (Exception)
    {
        MessageBox.Show("날짜형식에 맞지 않습니다." + Environment.NewLine + "다음과 같은 형식으로 입력하세요." + Environment.NewLine + " 2015-10-01, 2015.10.01, 2015/10/01, 2015 10 01");
    }
}


DateTime과 TimeSpan 둘 다 시간을 표현한다.
DateTime은 TimeSpan 자료형이 된다.
TotalSeconds : 시간(초)의 정수 부분과 소수 부분으로 표시된 현재 TimeSpan 구조체의 값을 가져온다.
https://msdn.microsoft.com/ko-kr/library/system.timespan%28v=vs.110%29.aspx


TimeSpan 예제가 있는 사이트

http://www.dotnetperls.com/timespan

'C# > 기능 활용' 카테고리의 다른 글

C# 자식폼 종료아이콘 클릭시 다른 이벤트 실행되게 하기  (0) 2015.11.30
C# DLL 만들기  (0) 2015.11.14
C# Get Mac Address  (0) 2015.10.12
C# Get IP Address (사설 IP, 공인 IP)  (0) 2015.10.11
C# 인코딩  (0) 2015.09.24
블로그 이미지

Link2Me

,