퇴근5분전


Unable to copy file "D:\Daebang\WPF_Login\Wpf.TabControl.dll" to "bin\Debug\Wpf.TabControl.dll". 'bin\Debug\Wpf.TabControl.dll' 경로에 대한 액세스가 거부되었습니다.

소스를 소스세이프에 바인딩 하면서 참조 경로 설정값을 특정 디렉토리로 변경해주었다.
이유는 기존에 따로 소스관리를 해주던 소스를 소스세이프로 통합관리 한다기에 옮겨주다보니 경로를 바꿔주어야 했었다.


바인딩하면서 경로를 바꿔주고 빌드를 하던중!! 한프로젝트에서 위와 같은 에러가 발생...


왜인지도 모르고 3시간을 다시 빌드를 하며 참조 dll을 다시 연결해주고.. 미친짓을 몇번이나 했으나...

아놔... 그닥 이유도 모른채 다시 빌드가 되었다. ㅡㅡ;;

추측 :  해당 프로젝트에 관련 된 프로젝트가 2개 있는데  그 두 프로젝트의 참조경로를 바꾸면서 '새로고침'을 안해서?
참조된 dll의 로컬경로 복사가 실행중에 다른 프로젝트의 관련 dll이 복사되면서 두 파일간 쫑이 난듯 한데...

정확한 이유를 잘 모르겠는뒝??? 음... 테스트를 한번 해볼까낭.

참조경로를 기존 경로로 하나 바꾸고 빌드를 해보자!!

ㅡ.,ㅡ 에러가 안뜬다!! 뭐쥐??



썅!! 이유도 모른채.. 해결되면 어쩌라는겨~~


음.. 컨트롤을 타원으로 회전시키는 메뉴들...

구심점에서 메뉴들이 빙글 빙글 돌아가는걸 욕심이 생겨 구현해보았다.

타원방정식을 이용하고 컨트롤들을 받아서 좌표값을 회전시키면서 재조정해주었더니 잘된다.

손수 삽질했던 공식으론 원만 그리다가... 타원으로 오니 일그러짐이 많이 생겨서... 타원방정식을 이용해서 둘다 해결하였다.

            // 타원방정식.  http://www.gisdeveloper.co.kr/497  타원방정식.
            // X(t) = Xc + A * cos(t)cos(각) - B * sin(t)sin(각);
            // Y(t) = Yc + A * cos(t)sin(각) + B * sin(t)cos(각);

이 공식을 보고 작업하였으며 

앞으로 나오면 BringToFront()  땡겨줬더니.. 대략 비스므리 하게 된듯 하다.

왼쪽은 컨트롤

오른쪽은 회전중에 스크린샷.

빨간 패널이 구심점이고  구심점을 기준으로 컨트롤들이 제각각 타원으로 회전한다.

독특한 메뉴구성이 필요하거나 할때 쓸모있을듯 한다.

수학이 딸리니 응용은 힘들다..



'# 1) 프로그래밍' 카테고리의 다른 글

TCP.IP 초기 구상 모델...  (0) 2010.05.09
미스테리... vs2008 오류..  (2) 2010.04.19
프로그래밍 설계?  (0) 2010.04.05
Xml 관련 객체가 한번더 정리가 되었다.  (0) 2010.04.01
XML 클래스다루기...  (0) 2010.03.31


 내가 프로그래밍을 접한지 3년이 넘었다.

회사 프로젝트를 하면서 여간 딴짓을 안해본적이 없다.  설계 라는게 한번에 와닿는게 아니기에 중간 중간 많은짓을 해본다.

나만에 방법론을 만들고 그 방법론이 실제 프로젝트와 얼마나 매칭이되는지도 살펴야 하고 다른부분이 어떤지도 파악해야하고 설계에서 구현과정을 담아보려고 무던히도 노력해보았다.

실제 설계 후 코드화 하는 구현단계까지 왔을때 난 여러가지 난관에 봉창한다.

생각지도 않았던 설계상에 오류. 누락된 객체표현등...

우선 내가 하는 방법은
1. 전체 프로젝트의 결과물을 그린다. (종이나 파워포인트에 UI를 그려놓는다 )
2. 이 결과물이 하는 일을 기록해준다.
3. 필요한 객체 목록들을 나열해본다. ( 객체들을 나열할때 시간소비가 많이 들어간다. 어떤객체가 얼만큼에 크기로 만들어져야 되는지.. 고민아닌 고민을 하게 된다. )
4. 객체간 관계를 따지고 언제 어떤데이타를 넘겨줄지 대략 그려본다.
5. 전체 결과물처럼 대략 추상화하여 구현 난이도를 결정해본다.
6. 코드에 들어간다.  각각 객체별 구현하는데 누락된부분은 다시 3번부터 재시작한다.

3~6까지를 두세번 반복하다보면 대충 결과물에 거의 근접해간다. 이때마다 새로운 기능들을 넣고 싶은 욕심이 생기는데
과감히 버려야 한다. 안그러면 네버엔딩스토리가 되므로...

개인 프로젝트를 계획하고 이를 구현하는데 있어서 위 방법으로 해보고 있는데 뭔가 빠진듯하고, 부족해보이는게 많다.

추상화에서 구현으로 들어올때, 추상화 된 부분이 많이 바뀐다. 이렇게 되면 추상화 했던 부분이 많이 바뀌므로 이를 이용한 객체들이 조금씩 틀어지는데 여기서 여러가지 문제가 터지더라...

경험 부족일까? 또는 추상화가 잘못된것일까? 앞으로도 계획된 몇가지 개인프로젝트가 있는데 이또한... 이런 과정을 거치면서 좀더 개발 방법론을 튼튼히... 하다보면.. 나중에 내가 주도하는 개발에 대해서 좀더 체계적으로 나갈수 있지 않을까?

현재 만들어놓은 프레임웍은 그 시초라고 볼수 있겠지만. 이 프레임웍은 현재 닷넷 개발에 쓰기엔 좀 뒤떨어진다.
앞으로의 트랜드에 맞춰서 나가려면 많은부분이 경량화 되고 차세대 버젼에 맞추어 발빠른 업그레이드가 필요한데... 과연
해낼수 있을까? 지금은 2.0이지만 올후반에는 3.5대로... 내년초에는 4.0으로... 빠르게 업그레이드를 해보아야 겠다.

앞으로 체계적인 방법론을 만들기 위해 노력하자.. 아자! 아자!

클래스에 Attribute를 붙여서 Xml화 하는 것에 대한 글을 썼었는데
바로 써먹으려니... 잘못된게 많아서 그것을 토대로 새롭게 바꾸어 나갔다.

Befor :  Add시 바로 Xml화 했던 것... 
After  : XmlTransform 객체를 두어 변환객체를 중간에 둠.

Load -- > 변경.... --> 저장 

루트로 가는것은 변경하지 않음. 

변경 시 Add할때 바로 Xml화 하던걸 다른 객체에 위임시켰고.

Add는 Add기능으로만 
내부적으로 XID라는 속성을 부여하고 이것을 이용한 Update, Delete를 구현하였음.

또 기존 XmlHelper 객체의 XmlElmt 를 확장하여 현재 XmlFileMng 객체가 쉽게 사용되어지도록 변경함.

물론 dll외부에서는 확장된 내용은 접근 못함. ( 굳이 노출시켜줄 이유가 없으므로.. 패쓰.. )
아 있다면 Element Name정도? 랄까?

Xml 관련 하여 기존 프로그램도 바꾸어야 되는가 싶었는데 영향은 없다.
업글차원에서라면 모를까 냅두자!!

원래는 네임스페이스를 나열하고 해당 객체들 멤버를 정리하려했으나.. 지금 말고 나중에 툴로 한번에 해야겠다!!

'# 1) 프로그래밍' 카테고리의 다른 글

컨트롤 타원 회전시키기...  (0) 2010.04.08
프로그래밍 설계?  (0) 2010.04.05
XML 클래스다루기...  (0) 2010.03.31
Attribute를 직접 정의해서 쓸줄이야...  (0) 2010.03.30
개발을 하다보니...  (0) 2010.03.29


집에서 각 Element를 수정 처리를 위해 고민중이었는데

아침 출근 버스에서 떠오른 생각이 있다.

XID 라는 고정 필드를 두는 방법

XmlBaseObject를 두고 여기에 Internal 필드 XID를 둔채로
작업을 한다.

저장시 리플랙팅 중 들어온 객체가 XmlBaseObject를 상속했는가를 체크 하고.

obj.GetType().IsS..( typeof( XmlBaseObject )) == true 이면... 캐스팅을 통해 XID를 부여하고
이값을 Element에 속성으로 추가!!


업데이트구문에서는 이 필드로 각 Element를 찾는 Key로 사용 , 삭제역시...

실제 클래스를 만들때는 XmlBaseObject를 상속하여 구현한다. 물론 없어도 저장되는건 차이가 없다.

업데이트나, 삭제를 따로 구현해야되는 귀차니즘이 생길뿐...

또한 이필드는 internal로 지정되있으므로  상속 후 구현되는 위치가 Xml Dll 외부라면 접근할수 없다!

xmlHelper를 조금 손봤는데... 이전에 작성한 프레임웍에 영향이 있을듯 싶다.

이러한 이유로 아직... 내공이 부족하다는것을 또한번 느낀다...






일정관리 프로그램을 설계중 데이타를 저장하고 꺼내 써야 하는 곳에 dB까지 쓸필요없으니 xml을 또 남용하자 하여

XmlHelper를 FileMng라 붙여서 매니져급을 만들었다.

이제 클래스 하나에 매니져 상속해서 저장하고 꺼내쓰면 된다 싶었는데... 왠걸..

데이타클래스가 세가지일때 세가지를 모두 정의해야 되는 상황이 발생하였다. 아.. 좀 애매한데... 싶어서..

어디선가 본 [DataContract]와 [DataMember] 를 찾아서 열심히 뒤지던중..

Hoons C# 강좌란에 김태훈님이 기록하신 글중 예제에 첨부된걸 보고 바로 MSDN검색에 들어갔으나..

아줸장... 예제 대로 쳐놓았으나.. 파일은 오간데 없고 저장이 되어도 xml형태가 아니다. 오~~ ...

이런걸로 시간끌수 없다라고 판단하여 조금더 고민끝에... Attribute라는 걸 다시 뒤적 뒤적...

이유인즉 XmlFile을 만들때 데이타를 일정한 구조로 XmlHelper를 통해 읽고 쓰고 하는데 이때

XmlHelper를 사용하는 클래스는 엘리멘트나 속성을 모두 상수로 지정해주었었다... 이리 조낸 복잡해진다.

이걸 그냥 Class 선언할때 Attribute로 붙이면 어떻게든 되지 않을까 싶었다.

솔직히 이전까지도 Attribute가 어떤놈인지 알고는 있는데 막상... 어따가 어떻게 써먹어? 했었는데...

이제 써먹을 수 있게 되었다. 

    [XmlRootTag("CATEGORY", "CODE")]
    public class JsFWCategory
    {
        string _Name = string.Empty;
        [XmlATT_Tag]
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        string _Desc = string.Empty;
        [XmlATT_Tag]
        public string Desc
        {
            get { return _Desc; }
            set { _Desc = value; }
        }
    }

위에 클래스가 XmlFileMng를 통해 XmlHelper로 전달되고 Xml파일 내 하나의 Element 행이 된다.

오.. 멋져..

이제부턴 상수선언할필요도 없고 넣을녀석 Class만 정의하고 던져주면 저장이 된다. 또 읽어올때는 object 주고, type지정해서 던져주면 꺼내올수 있다.


            CategoryTb c = new CategoryTb();  // XmlFileMng 를 이용할뿐...
            c.Load(); // XmlFile읽기.
- 저장할때
            JsFWCategory j = new JsFWCategory();
            j.Desc = "jsDEsc";
            j.Name = "jsNAme";

            c.AddRow(j);
            c.Save(); // 저장
- 꺼내올때
            XmlElmt exml = c.Find("015");  // xmlFile에서 ID값 015번에 Element를 찾아서 반환해줌.
            object obj = null;
            if( exml != null) obj = c.GetRow(exml, typeof(JsFWCategory));
            if (obj is JsFWCategory) this.textBox1.Text = ((JsFWCategory)obj).Name;


아래는 만들어진 내용... 

 <?xml version="1.0" encoding="utf-8" ?>

- <CATEGORY ID_IDENTITY="55">
    ... 생략...
        <CODE DESC="jsDEsc" ID="055" NAME="jsNAme" />
</CATEGORY>



완성!

이제 좀더 xml이 쉽게 다뤄질듯 함..

'# 1) 프로그래밍' 카테고리의 다른 글

Xml 관련 객체가 한번더 정리가 되었다.  (0) 2010.04.01
XML 클래스다루기...  (0) 2010.03.31
개발을 하다보니...  (0) 2010.03.29
배열 정렬하기...?  (0) 2010.02.25
Enum객체 관련 설명.  (0) 2010.02.10


 프레임웍을 개발하다보니 실제적으로 객체를 추상화한후 이를 구체화 하고 구현하기 시작하면서
눈덩이처럼 불어나는 객체 크기가... 아.. 아직 실력이 멀었구나 싶었다.
메서드 하나 들어날때마다 추가되는 변수들이 정말 필요한것인가를 생각하다 일정을 미루기 그래서
구현부터 하다보면 어느새 객체는 내가 생각했던것 이상으로 부풀어 있었다.
객체와 객체간에 메세지 통신을 규격화 하는데 있어서 대리자를 적절히 써서 dll내부에 감춤으로써 외부에 노출되지 않도록 하는게 조금 시간을 많이 잡아먹었다.
internal 키워드를 이용하는 방법이 나름 잘 써먹었다.

 객체들을 추상화 하다보면 안보이던것들이 구현하면서 부족한 객체들이 하나 둘 나올땐.... 아 그땐 왜 생각을 못했을까 싶었다.

 이번에 만들 일정관리(NEW)는 좀더 추상화작업과 구체화 작업들을 좀더 체계적으로 바꿔나가야겠다.
자료는 기존과 같이 xml을 이용하고 내가 만든 개발프레임웍을 이용하면 좀더 빠르게 만들어낼수 있을듯 하다.

이번에도 컨트롤을 만들어야 할까? 아님 만들어둔 것들로 가능하려낭...?



'# 1) 프로그래밍' 카테고리의 다른 글

XML 클래스다루기...  (0) 2010.03.31
Attribute를 직접 정의해서 쓸줄이야...  (0) 2010.03.30
배열 정렬하기...?  (0) 2010.02.25
Enum객체 관련 설명.  (0) 2010.02.10
삼항연산자 중복...  (0) 2010.02.05



 쉬운 것인뎅...

1 5 11 2 8 66 7 121 6 77 25 48 442 0 이런 불규칙적인 숫자가 있을시..

이걸 c에선 정렬방법에 따라 구현했어야 했지만.

C#은 간단하게 해결이 가능하다.

 private void button1_Click(object sender, EventArgs e)
        {
            string[] Numbers = this.textBox1.Text.Split(' '); // textBox는 무정렬 숫자배열을 가진 컨트롤임.

            int[] Numbers_int = new int[Numbers.Length];

            for (int i = 0; i < Numbers.Length; i++)
                Numbers_int[i] = Convert.ToInt32(Numbers[i]);
           
            //Array.Sort<int>( Numbers_int , fnCompare );
            Array.Sort<int>(Numbers_int);

            foreach (int num in Numbers_int)
                this.textBox2.Text += num.ToString() + " ";
        }

        int fnCompare(int s1, int s2)
        {           
            return s1.CompareTo(s2);
        }



결과는 0 1 2 5 6 7 8 11 25 48 66 77 121 442  이다.

음... 너무 쉬운가?


 

훈스닷넷에 있는 질문글에 대한 답글로 밥먹기 전에 적어보았다...

열거형의 인덱스로 접근할수 있는 방법 vs2005에서는
Enum.GetValues(typeof(DayOfWeek))[1]  <--이렇게 바로 []인덱스를 붙였던것 같은데...
2008에선 안되넹.. 반환타입이 Array라고 해서.. .GetValue 메서드를 이용해서 추출한다.


object dayofWeek = Enum.GetValues(typeof(DayOfWeek)).GetValue(0);
MessageBox.Show( dayofWeek.ToString() );





아래는 해당 요일을 시작요일로 바꾸고자 할때.

            this.Text =  ((((int)DayOfWeek.Sunday) + (int)DayOfWeek.Tuesday) % 7) .ToString();
            this.Text += ((((int)DayOfWeek.Monday) + (int)DayOfWeek.Tuesday) % 7).ToString();
            this.Text += ((((int)DayOfWeek.Tuesday) + (int)DayOfWeek.Tuesday) % 7).ToString();
            this.Text += ((((int)DayOfWeek.Wednesday) + (int)DayOfWeek.Tuesday) % 7).ToString();
            this.Text += ((((int)DayOfWeek.Thursday) + (int)DayOfWeek.Tuesday) % 7).ToString();
            this.Text += ((((int)DayOfWeek.Friday) + (int)DayOfWeek.Tuesday) % 7).ToString();
            this.Text += ((((int)DayOfWeek.Saturday) + (int)DayOfWeek.Tuesday) % 7).ToString();

DayOfWeek.Tuesday 기준일로 부터 들어오는 각 요일에 대해 인덱스값을 뽑아낼수 있게됨.

뭐 어렵지 않으니...그닥 설명할것도 없눼...........  

  예전에 본것같은데 기억이 안나서 

직접 해놓고 해당 값이 어떻게 출력되는지 뽑아 보았다. 

왜썼는지는 일끝나고... 추가.. 


  public Form1()
        {
            InitializeComponent();


            //null;
            string Target = "ㅁㅁㅁ";
            this.Text = Target == null ? 1 > 0 ? "_1" : "_2" : "_3" ;
            /*
             *     조건 1    조건 2      결과
             *       참       참          _1      
             *       참       거짓       _2
             *      거짓      거짓      _3
             *      거짓      참         _3
             */


            //   this.Text = Target ?? (Target != null ? "!" : "_"); // 결과는 _  null이니까.

        }


추가 내용 : 
소스 상에서 특정 변수값이 null인지를 따져야 하고  다음으로 이값이 어떤 특정값인지체크 하기 위해 작성을 하다보면

간혹 이런 코드라인이 한두줄 걸쳐서 나올때 if문 갯수가 눈을 어지럽히게 된다.

if( 객체 != null && 객체 == 특정값)
{
         처리1;
}     
else
{
         처리 2;
}
.. 한두줄 다른거 체크

if( ... 위에 로직 반복... )

.. 한두줄 다른거 체크..

이러다보면 몇라인 보지도 못하고 화면을 계속 스크롤 해야 하는 경우가 생기는데..

삼항 연산자를 중복으로 사용하여 같은 처리 로직을 만든다 .


물론  조건1?  조건2 ? 조건1 && 조건2 가 참  :   조건1 참 , 조건2 거짓  : 조건1이 거짓 ;

로직을 모를경우 문제가 되겠지만... 이런건 간단한 주석으로 알려줄수 있는 문제이다.


위를 간단히 해석하고 싶으면 () 를 이용하면 된다 .


조건1? ( 조건2 ? 조건1 && 조건2 가 참  :   조건1 참 , 조건2 거짓  ) : 조건1이 거짓 ;

조건 1 에 걸렸을때  
참    ->(      다음 조건식  => 참   -> 첫번째 반환값이 ,  
                                        거짓 -> 다음식에 거짓값인 가운데 값이 반환 )
거짓 -> 끝에 거짓 값이 반환

















null ? 1 > 0 ? "_1" : "_2" : "_3" ;