블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2738)
Unity3D (817)
Programming (475)
Python (8)
TinyXML (5)
STL (13)
D3D (3)
MFC (1)
C/C++ (54)
C++/CLI (45)
C# (250)
WinForm (6)
WPF (5)
Math (10)
A.I. (1)
Win32API (11)
Algorithm (3)
Design Pattern (7)
UML (1)
MaxScript (1)
FMOD (4)
FX Studio (1)
Lua (2)
Terrain (1)
Shader (3)
boost (2)
Xml (2)
JSON (4)
Etc (11)
Monad (1)
Html5 (4)
Qt (1)
Houdini (0)
Regex (11)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (228)
협업 (58)
3DS Max (3)
Game (12)
Utility (136)
Etc (96)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (53)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday
04-30 00:00

어제 프로젝트 관련된 코딩을 하다가 난수를 써야 할 일이 있어서
C#의 Random Class에 관해 알아 보았다!

사실 Random Class의 사용방법은 그리 복잡하지도 어렵지도 않지만;
내가 만들고 싶은 난수가 적절히 만들어 지지 않아 몇시간을 테스트한김에
이와 관련된 포스팅을 하게 되었다;

예전 C언어나 C++의 rand() 함수를 사용할때는

int random = rand()%50;
위의 코드를 수행하게 되면 random 변수에는 에는 0부터 49까지 난수가 들어가게 된다;
rand()에sms seed 값이 있어 저렇게만 수행할 경우
만약 랜덤한 수가 1 3 6 2 6 순으로 나왔다면; 프로그램을 껏다 켜도 똑같은 패턴으로 나오게 된다;
그래서 아래의 항목을 추가하게 되면 그것을 막을 수 있었다;

srand(time(NULL)); // 시간에 따른 난수 발생, 없을경우 실행때마다 같은 난수가 발생한다.


이제 C# 의 Random Class를 보자;

사용법 정말 간단하다;

Random r  = new Random();

생성자는 오버로딩 되어있어 생성시 시드값을 정할수 있고! 정하지 않을수 있다;

정할경우 위에 말한대로 계속 똑같은 패턴의 난수가 발생하며 디폴트일 경우에는 시스템의 시간을 이용하여 
시드값을 정하기 때문에 매번 다른 패턴의 난수
가 발생한다;

제공하는 매소드를 알아보자;

r.Next() : 범위가 없는 랜덤한 값을 리턴한다
r.Next(int maxValue) : 난수의 범위의 상한을 지정
r.Next(int minValue, int maxValue) : 난수의 범위의 하한과 상한을 지정!


여기서 중요한것은 난수의 하한은 난수에 포함 되지만 상한은 포함 되지 않는다는것이다;
즉 1부터 10의 값을 난수로 얻고 싶을때 Next(1,10); 을 호출하면 10은 죽어도 안나온다는 말인다;;
10을 난수로 얻고 싶다면 Next(1,11)을 호출 해야한다;

그외에
r.NextBytes()
r.NextDouble() 
메소드가 있는데 int값만 필요해서 사용하지는 않았지만 메소드 명으로 쉽게 짐작 할수 있다;

이제 본론으로 들어가서 이렇게 간단한 Random Class의 사용방법을  포스팅을 하게 된 이유는
내가 발생하고 싶은 난수가 특정시간에 여러개의 객체를 생성할때 각각의 객체마다 다른 
난수를 가지고 있게 하고 싶었지만 Seed값을 기본적으로 시간을 사용하기 때문에 
할수가 없어서이다;

다음의 예제를 보면;
class Program
{
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Item item = new Item();
            }
        }
}

class Item
{
        int num1;
        int num2;
        public Item()
        {
            Random r = new Random();
            num1 = r.Next(1, 100);
            num2 = r.Next(100, 200);
            Console.WriteLine("{0} , {1}", num1, num2);
        }
}



매우 간단한 구조이다 Main()에서는 Item 객체를 10개 만들고 
Item 객체의 생성자에서는 난수를 2개 (각각 1~99, 100~199 범위의 값) 발생시켜
출력한다;

어떤 결과가 나올까? 10개의 객체는 각각 다른 난수를 가지고 있을까?

-- 실행 결과 --

결과처럼 '아니오' 이다; 

이와 같은 발생의 이유는 기본적으로 난수발생의 시드가 시간이기 떄문이다;
위에 예제처럼 빠르게 10개의 객체를 생성할 경우 시드가 같아져 같은 결과가 나오는것이다;

어떻게 해결할까?

밑의 두가지 예제의 차이를 알게되면 쉽게 해결 가능하다;
예제1)
Random
r = new Random();
for (int i = 0; i < 10; i++)
{
     Console.WriteLine("{0}", r.Next());               
}

예제2)
for (int i = 0; i < 10; i++)
{
     Random r = new Random();
     Console.WriteLine("{0}", r.Next());
}

--결과 화면--


화면에서 보다싶이 Random 객체를 빠르게 10번 생성한 예제 2에서는  같은 번호가 나왔고
객체를 재사용한 예제1에서는 다른 결과가 나왔다;


이 차이를 이용해 위에서 실패한 Item class에 랜덤한값을 배치 할수 있는것이다;

Random 객체를 static으로 두고 하나만 계속 사용한다면 위의 예제도 우리가 원하는 난수를 갖게 될것이다;


출처 : http://crynut84.tistory.com/15

반응형

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

이펙티브 C# - 요점 정리  (0) 2010.07.19
Form Show()/Hide()  (0) 2010.07.19
화살표 그리기(.NET Pen Class)  (0) 2010.07.16
.NET 중복 실행 방지  (0) 2010.07.16
App.Config XML읽고 쓰기..  (0) 2010.07.15
Posted by blueasa
, |

안녕하세요? 맨날맑음입니다.

화살표를 그려야 할 일이 생겨서 어떻게 그릴까 생각하다가, Line을 여러개 그려서 화살표를 만들려고 했습니다.
선의 각도에 따라 화살표 머리 부분의 각도가 변하기 때문에 수학을 못하는 저로써는 화살표 그리는 것 조차도 힘든일이 었습니다.

하지만! .NET의 Pen 클래스는 Line의 끝점들의 모양을 변경시켜 주는 기능을 제공합니다.
Pen 클래스의 좀더 자세한 설명은 아래의 MSDN 도움말을 참조 하시면 됩니다.
http://msdn.microsoft.com/ko-kr/library/system.drawing.pen(en-us,VS.85).aspx

MSDN에서 Pen 클래스의 속성을 보면 StartCap 과 EndCap이 있습니다. 이것이 선의 끝모양을 지정하는 속성입니다. 그럼 선의 시작과 끝 모양을 화살표로 바꾸어 보겠습니다.

Pen pen = new Pen(Color.Blue, 6);
pen.StartCap = LineCap.ArrowAnchor;
pen.EndCap = LineCap.ArrowAnchor;
위의 소스에서 처럼 Pen 객체를 생성하고, 해당하는Cap 속성을 바꿔주는 아주 간단한 방법으로 끝모양을 바꿔줄 수 있습니다.  LineCap 사용을 위해서는 using System.Drawing.Drawing2D;을 해주셔야 합니다.
화살표 모양 이외에도 여러 모양을 지정 할 수 있습니다. LineCap 을 살펴 보면 열거형으로 되어 있습니다. 각각의 멤버의 의미를 보면 다음과 같습니다.
Flat : 일직선 형태의 끝 모양을 지정합니다.
Square : 정사각형 형태의 선 끝 모양을 지정합니다.
Round : 둥근 선 끝 모양을 지정합니다.
Triangle : 삼각형 선 끝 모양을 지정합니다.
NoAnchor : 앵커를 지정하지 않습니다.
SquareAnchor : 정사각형 앵커 선 끝 모양을 지정합니다.
RoundAnchor : 둥근 앵커 끝 모양을 지정합니다.
DiamondAnchor : 다이아몬드 앵커 끝 모양을 지정합니다.

ArrowAnchor : 화살표 모양의 앵커를 지정합니다.
Custom : 사용자 지정 선 끝 모양을 지정합니다.

AnchorMask : 선 끝 모양이 앵커 모양인지 여부를 검사하는 데 사용되는 마스크를 지정합니다.
아래와 같이 간단하게 Windows Form 프로젝트를 생성해서 Paint 이벤트 핸들러에서 화살표를 그려 보겠습니다.

using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Paint += new PaintEventHandler(Form1_Paint);
        }

        void Form1_Paint(object sender, PaintEventArgs e)
        {
            Pen pen = new Pen(Color.Blue, 6); //Pen 객체 생성
            pen.StartCap = LineCap.ArrowAnchor; //Line의 시작점 모양 변경
            pen.EndCap = LineCap.ArrowAnchor; //Line의 끝점 모양 변경
            e.Graphics.DrawLine(pen, 20, 50, 300,50); //Line 그리기
        }
    }
}
 
이와같이 복잡한 화살표 알고리즘 없이 Pen 클래스의 속성 변경 만으로도 간단하게 화살표를 그릴 수 있습니다.
참 쉽죠잉~


출처 : http://crynut84.tistory.com/48
반응형

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

Form Show()/Hide()  (0) 2010.07.19
Random Class를 파해쳐 보자!  (0) 2010.07.16
.NET 중복 실행 방지  (0) 2010.07.16
App.Config XML읽고 쓰기..  (0) 2010.07.15
ini파일을 간단히...사용하자.  (0) 2010.07.15
Posted by blueasa
, |
안녕하세요? 맨날맑음 입니다.

어플리케이션을 개발 하다 보면 같은 프로그램이 두번 실행 되지 않아야 하는 경우가 종종 생깁니다.
이를 해결 하기 위해 여러 방법이 있지만.. 이번 포스팅에 소개 할 내용은 커널 동기화 객체 중 하나인 뮤텍스(Mutex)를 이용하여 해결하는 방법을 소개하려 합니다.

Mutex는 .NET의 System.Threding 네이스페이스에 포함된 클래스 입니다. 사실 둘이상의 스레드가 동시에 공유될 수 있는 리소스에 접근 할때 데드락의 위험이 있으므로 동기화 매커니즘이 필요하게 되는데요. Mutex는 리소스에 대한 단독 엑세스 권한을 하나의 스레드에만 부여하여 동기화하는 기본형식 입니다.
같은 리소스에 접근 할때 하나의 스레드가 Mutex를 걸고 어떠한 일을 수행 할 경우 다른 스레드는 먼저 수행하고 있는 스레드가 Mutex를 해제 할때까지 기다리게(일시중지) 되게 됩니다.
Mutex에 관한 자세한 설명은 아래의 링크에서 MSDN 도움말을 확인 할 수 있습니다.
http://msdn.microsoft.com/ko-kr/library/system.threading.mutex.mutex.aspx

테스트 하는 어플리케이션으로는 Windows Form 프로젝트를 예로 들겠습니다.
WinForm 프로젝트를 생성하면 Program.cs 가 생성 됩니다.
Main 함수에 다음과 같은 코드를 추가 시켜 주면 메세지 막스가 뜨면서 해당하는 프로그램이 중복 실행 되었다는걸 알릴 수 있습니다. 매우 간단하죠?
static class Program
    {
        /// 
        /// 해당 응용 프로그램의 주 진입점입니다.
        /// 
        [STAThread]
        static void Main()
        {
            bool createdNew;
            Mutex dup = new Mutex(true, "Focus Explorer Mutex", out createdNew); //Mutex생성
            if (createdNew)
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new MainForm());
                dup.ReleaseMutex(); //Mutex 해제
            }
            else // 프로그램이 중복 실행된 경우
            {
                MessageBox.Show("이미 프로그램이 실행중입니다.","Focus Explorer");
            }
        }
    }
 
우선 Mutex를 생성하고, 생성자에 두번째 인자에 뮤텍스 이름을 지정합니다.
세번째 인자로준 bool 값이 false일 경우 이미 뮤텍스가 걸리있는 상태이기 때문에.. 해당 프로젝트가 이미 생성되었다고 생각하고 프로그램이 실행중이라는 메세지 박스를 띄우고, 프로그램을 종료합니다.

이상 간단한 Mutex를 사용한 프로그램 중복 방지 방법이었습니다.


출처 : http://crynut84.tistory.com/46
반응형

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

Random Class를 파해쳐 보자!  (0) 2010.07.16
화살표 그리기(.NET Pen Class)  (0) 2010.07.16
App.Config XML읽고 쓰기..  (0) 2010.07.15
ini파일을 간단히...사용하자.  (0) 2010.07.15
C# (윈폼/콘솔) 관련 사이트  (0) 2010.07.15
Posted by blueasa
, |

App.Config XML파일을 읽고 쓰는 간단한 함수를 하나 만들어 봤습니다..

더 좋은 정보 있으면 리플 달아 주세요

 

 

private string AppConfigRead(string keyName)

        {

            string strReturn;

            Configuration currentConfig =

                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

 

            if (currentConfig.AppSettings.Settings.AllKeys.Contains(keyName))

                strReturn = currentConfig.AppSettings.Settings[keyName].Value;

            else

                strReturn = ""; //키가없으면.

 

            return strReturn;

        }

 

        private bool AppConfigWrite(string keyName, string value)

        {

            Configuration currentConfig =

                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

 

            if (currentConfig.AppSettings.Settings.AllKeys.Contains(keyName)) //키가 있으면

                currentConfig.AppSettings.Settings[keyName].Value = value;

            else       //키가 없으면

                currentConfig.AppSettings.Settings.Add(keyName, value);

           

            currentConfig.Save();

            ConfigurationManager.RefreshSection("appSettings");   // 내용 갱신             

            return true;

        }


출처 : http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNo=8&no=1699&ref=1699



우선 위 함수를 사용하려면 참조 추가와 namespace 추가가 필요합니다.
1) System.configuration <- 참조 추가
2) using System.Configuration; <- 추가

그렇게 하고도.. 위의 소스에서 Contains 라는걸 찾을 수 없어서 제맘대로 수정했습니다.
정석인진 모르겠지만..돌아가니 참고하실분은 하세요.


        public static string AppConfigRead(string keyName)
        {
            string strReturn = "";
            Configuration currentConfig =
                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            bool bIsKey = false;

            foreach (string key in currentConfig.AppSettings.Settings.AllKeys)
            {
                if (key.StartsWith(keyName))
                {
                    strReturn = currentConfig.AppSettings.Settings[keyName].Value;
                    bIsKey = true;
                    break;
                }
            }

            if(bIsKey == false)
                return string.Empty;
           
            return strReturn;
        }


        public static bool AppConfigWrite(string keyName, string value)
        {
            Configuration currentConfig =
                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            if (currentConfig.AppSettings.Settings.Count != 0)
            {
                bool bIsKey = false;
                foreach (string key in currentConfig.AppSettings.Settings.AllKeys)
                {
                    if (key.StartsWith(keyName))
                    {
                        currentConfig.AppSettings.Settings[keyName].Value = value;
                        bIsKey = true;
                        break;
                    }
                }

                if ( bIsKey == false )       //키가 없으면
                {
                    currentConfig.AppSettings.Settings.Add(keyName, value);
                }
            }
            else
            {
                currentConfig.AppSettings.Settings.Add(keyName, value);
            }

            currentConfig.Save();
            ConfigurationManager.RefreshSection("appSettings");   // 내용 갱신             

            return true;
        }

반응형
Posted by blueasa
, |

질문 & 답변에 관련 내용이 많지만...

널리 사용하시라고 올려 봅니다.

 

다음과 같이 class를 추가해서 사용하시면

사용하시기 편리 하실거예요.

 

추신 : 파일명 및 파일 패스(path)를 수정하여 사용하세요. 감사합니다.

 

//ini 관리 클래스
    public class IniControl
    {

        [DllImport("kernel32")]

        public static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);

        [DllImport("kernel32")]

        public static extern uint GetPrivateProfileInt(string lpAppName, string lpKeyName, int nDefault, string lpFileName);

        [DllImport("kernel32")]

        public static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);

        public static int ReadInteger(string fileName, string IpAppName, string IpKeyName, int Default)
        {
            try
            {
                string inifile = fileName;    //Path + File

                StringBuilder result = new StringBuilder(255);
                IniControl.GetPrivateProfileString(IpAppName, IpKeyName, "error", result, 255, inifile);

                if (result.ToString() == "error")
                {
                    return Default;
                }
                else
                {
                    return Convert.ToInt16(result);
                }
            }
            catch
            {
                return Default;
            }
        }

        public static Boolean ReadBool(string fileName, string IpAppName, string IpKeyName)
        {
            string inifile = fileName;    //Path + File
            StringBuilder result = new StringBuilder(255);
            IniControl.GetPrivateProfileString(IpAppName, IpKeyName, "error", result, 255, inifile);

            if (result.ToString() == "True" || result.ToString() == "1")
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        public static string ReadString(string fileName, string IpAppName, string IpKeyName, string Default)
        {
            string inifile = fileName;    //Path + File

            StringBuilder result = new StringBuilder(255);
            IniControl.GetPrivateProfileString(IpAppName, IpKeyName, "error", result, 255, inifile);

            if (result.ToString() == "error")
            {
                return Default;
            }
            else
            {
                return result.ToString();
            }

        }

        public static string getIni(string fileName, string IpAppName, string IpKeyName)
        {
            string inifile = fileName;    //Path + File

            StringBuilder result = new StringBuilder(255);
            IniControl.GetPrivateProfileString(IpAppName, IpKeyName, "error", result, 255, inifile);

            return result.ToString();

        }

        public static Boolean setIni(string fileName, string IpAppName, string IpKeyName, string IpValue)
        {
            string inifile = fileName;    //Path + File
            IniControl.WritePrivateProfileString(IpAppName, IpKeyName, IpValue, inifile);

            return true;
        }
        public static Boolean setIni(string filePath, string fileName, string IpAppName, string IpKeyName, string IpValue)
        {
            string inifile = filePath + fileName;
            IniControl.WritePrivateProfileString(IpAppName, IpKeyName, IpValue, inifile);

            return true;
        }
    }

 

 

질문은 언제나 환영입니다.

즐프하세요.


출처 : http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=18&MAEULNO=8&no=1818&page=3

반응형
Posted by blueasa
, |
반응형
Posted by blueasa
, |

C#으로 ESC키 무시 방법을 찾는데 왜 찾는 녀석은 안나오고... C++에서의 방법들만 나오는지 ㅡ_ㅢ;;
에효.. 암튼... 언제든 쓸모가 있을 듯 하니... 한번 옮겨놔 보련다.....


1. Enter, ESC 키 무시 방법

모달리스 다이얼로그를 만들고 이 ESC,ENTER 키를 입력하면 다이얼로그가 사라지게 됩니다. 그렇다고 꼭 이 키를 무시해야 한다는 건 아니고 경우에 따라 무시를 해도 되고 다른 동작을 하게해도 됩니다. 이는 개발자 마음!!
모달리스 다이얼로그 클래스에서 PreTranslateMessage()를 아래와 같이 오버라이딩 해주면 됩니다.


/*
     ESC, Enter key를 무시한다.
*/
BOOL CProcessADlg::PreTranslateMessage(MSG* pMsg)
{
    // TODO: Add your specialized code here and/or call the base class
    switch(pMsg->message)
    {
    case WM_KEYDOWN:
        {
            switch(pMsg->wParam)
            {
            case VK_ESCAPE:
            case VK_RETURN:
                return TRUE;
            }
        }
    }
    return CDialog::PreTranslateMessage(pMsg);
}


2. 소멸 방법

모 달리스 다이얼로그를 소멸하려면 두 가지 측면에서 생각해야 합니다. 하나는 모달리스 다이얼로그를 생성하는 부모 윈도우 객체이고 하나는 모달리스 다이얼로그 자신입니다.  부모 윈도우 객체에서는 모달리스 다이얼로그를 생성할 때 모달리스 다이얼로그 객체 변수를 정한 후 메모리 할당을 하고 Create()함수를 호출하여 생성하게 됩니다. 그렇다면 모달리스 다이얼로그가 파괴 될 때 부모 윈도우가 이를 알 수 있어야 메모리 해제를 제대로 해 줄 수 있습니다. 제가 사용한 방식은 모달리스 다이얼로그 객체에서 자기 자신의 메모리를 해제하고 부모 윈도우에서는 모달리스 다이얼로그 객체변수에 NULL 포인터를 전달하는 방식을 사용했습니다. 이렇게 하기 위해서 모달리스 다이얼로그의 PostNcDestroy()가 호출 되는 시점에서 부모 윈도우에게 사용자 정의 메시지(저는 WM_DESTROY_DLG라고 정했습니다.)를 하나 정해서 SendMessage함수를 통해서 메시지를 전달해 주고 부모 윈도우에서는 이 메시지를 처리합니다. 그리고 모달리스 다이얼로그에서 자기 자신의 메모리를 해제 합니다. 이 과정에 대해서는 예제 소스를 함께 첩부해 놓았습니다. 말로 설명해보려고 했는데 글 재주가 없어서;;


※ 위 글에 대한 잘못된 부분이나 궁금하신 부분에 대한 피드백은 언제나 환영입니다 ~ 물론, 퍼가신다면 영광이구요. 우리나라의 모든 개발자 분들께서 바쁘시지만 서로 자신의 귀중한 경험과 지식을 공유해서 함께 발전해 나갈 수 있었으면 합니다 ^^

Dialog.zip


출처: greenfrog님의 블로그 - Programmer greenfrog!!

반응형
Posted by blueasa
, |

Form 에서 다른 Form 을 생성하는 경우 작업표시줄에도 표시되고 Alt+Tab을 누르면 나오는 화면에도 나옵니다.

이것을 없애는 방법이 여러가지 있습니다.

ShowDialog() 로 호출하는 방법도 있고, FormBorderStyle을 FixedToolWindow 또는 SizableToolWindow 로 지정하면 Alt+Tab 화면에 보이지 않습니다. 하지만 이 방법들은 무언가 꺼림찍하죠?

다들 특정한 목적으로 쓰도록 만든 것이기 때문에 일반 폼에 적용하기는 무리가 있습니다.

제가 만드는 App의 경우에는 FormBorderStyle을 None으로 설정하고, 소유하는 폼에도 접근해서 작업을 하도록 만들었기 때문에 위의 방법을 쓸 수가 없더군요

 

그래서 열심히 구굴링을 해서 찾아낸 방법!

        protected override CreateParams CreateParams
        {
            get
            {
                // Turn on WS_EX_TOOLWINDOW style bit
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x80;
                return cp;
            }

         }

이 코드를 Form의 클래스에 넣기만 하면 Alt+Tab을 눌러도 보이지 않습니다.
보니까 어떤 속성을 오버라이드 해서 ToolWindow 속성을 부여하는 것 같습니다. 정확한지는 저도 잘 ^^;

 

출처: http://www.csharp411.com/hide-form-from-alttab/

반응형
Posted by blueasa
, |

Form.Location 이라는 속성을 이용해서 창의 위치를 결정할 수 있습니다.
그리고 Form.Show() 라는 메써드를 이용해서 창을 보여줄 수 있습니다.
그렇다면!!
위치를 지정하고 그 위치에 창을 띄울 수 있을 것 같은데... 어라? 잘 안됩니다 ㅡㅡ;
일단 Show() 메써드를 사용한 후에는 Location 속성을 이용해서 창이 잘 움직이는데 처음 시작할 때는 잘 안되는군요~
Show() 메써드를 실행하기 전에 지정한 Location 속성은 Form의 위치에 영향을 주지 못하는 것 같습니다.

이럴 때!!
Form.StartPosition 속성을 이용합니다.
오호라! 시작 위치를 지정할 수 있을 것 같은 속성 이름이군요!

Form.StartPosition 속성은 Point 객체가 아니고 FormStartPosition 이라는 열거형입니다.
그렇다면 어떻게 처음 위치를 지정할까요?

Form.StartPosition = FormStartPosition.Manual; //이렇게 지정해 주면 Location을 시작 위치로 사용합니다.
이 방법을 사용하면 Form을 원하는 위치에 띄울 수 있겠죠? ^^

form1.StartPosition = FormStartPosition.Manual;
form1.Location = new Point(10,10);
form1.Show();


이렇게요~ 참 쉽죠?

반응형
Posted by blueasa
, |

사용자 삽입 이미지
입력 배열 :

        string[] parentString = { "son1", "son2", "son3", "son4" };
        string[] childString = { "byoung1", "byoung2", "byoung3" };

입력방법 #1

        private void button1_Click(object sender, EventArgs e)
        {
            treeView1.Nodes.Clear();
            treeView1.BeginUpdate();

            foreach (string str in parentString)
            {
                TreeNode tn = treeView1.Nodes.Add(str);

                foreach (string substr in childString)
                {
                    tn.Nodes.Add(substr);
                }
            }

            treeView1.EndUpdate();
        }

입력방법 #2

        private void button2_Click(object sender, EventArgs e)
        {
            treeView1.Nodes.Clear();
            treeView1.BeginUpdate();

            foreach (string str in parentString)
            {
                treeView1.Nodes.Add(str);
            }

            foreach (TreeNode tn in treeView1.Nodes)
            {
                foreach (string substr in childString)
                {
                    tn.Nodes.Add(substr);
                }
            }

            treeView1.EndUpdate();
        }

입력방법 #3

        private void button3_Click(object sender, EventArgs e)
        {
            treeView1.Nodes.Clear();
            treeView1.BeginUpdate();

            TreeNode tn = new TreeNode();
            foreach (string str in childString)
            {
                tn.Nodes.Add(str);
            }

            foreach (string str in parentString)
            {
                TreeNode tnParent = treeView1.Nodes.Add(str);
            }

            treeView1.EndUpdate();
        }



출처 : http://www.iamgsi.com/entry/C-TreeView-내용-추가하기
반응형
Posted by blueasa
, |