다른게 있을지 모르지만. 찾은게 이거라서.. (--)

실버라이트에서 특정 시간에(특정 시간이 흘렀을때) 뭔가 해줘야 할때 쓰면 좋습니다. 흐흐

몰라서 그렇지 알고 나면 아주 간단합니다.

DispatcherTimer 형식의 인스턴스를 만들어 주고
시간간격을 Interval 로 정해주고
Tick 이벤트 만들어줘서 실제로 수행할 일을 정해주고
Start(혹은 Stop) 해주면 끝입니다.


예를 들어보자면

DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(3) };

이런놈을 멤버변수 정도로 만들어주고(시간간격은 3초가 됩니다)

특정부분에서(로드시라든지 뭐..)

timer.Tick += new EventHandler(timer_Tick);

이렇게 이벤트 만들어주고

void timer_Tick(object sender, EventArgs e)
{
//안에 수행할 일들 넣어주고
}

이 타이머(?) 를 시작시킬 위치에서

timer.Start() ;

해주면 끗!!!

간단하네요~
by 피요히코~ 2010. 9. 28. 20:34

간만에 하고 있는 실버라이트....
자주 써야 할꺼 같은걸 하나 정리합니다~

뭐 다른데서도 마찬가지지만
실버라이트에서도 프로그램 실행시 사용되는 이미지등을 리소스로 따로 모아두고 사용합니다.
이 리소스는 빌드액션(Build Action)방식에 따라 패키지되는 방식을 정할수 있는데

빌드액션은 다름 세가지로 분류됩니다.

1. None(없음) - 없으니까 리소스를 포함하지 않는거죠
2. Content(내용) - 리소스를 프로젝트 패키지파일(*.xap)파일에 포함합니다.
3. Resource(리소스) - 리소스를 프로젝트의 어셈블리파일(*.dll)에 포합합니다.


간단해 보이는 내용인데 왜 이걸 정리하느냐??
빌드액션에 따라서 리소스 참조 URI가 달라지기 때문이죠...(아.. 헷깔린다... ㅠ-ㅠ)

URI는 경로를 나타내므로 (당연히)상대경로와 절대경로가 있습니다.
그리고 참조해야 하는 리소스는
해당 프로그램의 패키지파일을 기준으로 패키지보다 상위에 있을수도 있고
패키지와 같은레벨에 있을수도
패키지 하위에 있을수도
패키지 하위의 어셈블리에 있을수도 있죠

1. 패키지보다 상위레벨에 존재하는 리소스의 경우에는 상대경로는 사용할 수 없습니다.  닥치고 절대경로...
   (ex : http://bravochoi.tistory.com/images/sample.jpg ) ( 없는 경로니 눌르는일 없도록... ㄷㄷㄷ)
2. 패키지와 같거나 하위레벨에 존재하는 리소스의 경우에는 상대/절대 경로 모두 사용 가능합니다. 
   (ex : http://bravochoi.tistory.com/resources/images/sample.jpg  절대경로)
   (ex : /resources/images/sample.jpg  상대경로)
   (ex : resources/images/sample.jpg   상대경로2)
3. 어셈블리에 들어있는 경우에는 /어셈블리명;component/경로 와 같은 형식으로 사용가능합니다.
   (ex : 패키지에 있는 resources.dll이라는 어셈블리에 sample.jpg가 있는 경우
           /resources;compenet/sample.jpg  요렇게)
4. 빌드애션을 Content로 해서 리소스가 패키지에 포함된 경우에는 상대경로로 접근해야 하며 시작은 / 로 해야됩니다
   (ex : /sample.jpg)
5. 빌드액션을 Resource로 해서 리소스가 프로젝트의 어셈블리에 포함되어 있을때는 상대경로로 접근해야 하며 / 를 붙이면 안됩니다.
   (ex : sample.jpg)
   (ex : images/sample.jpg)

3번과 5번의 차이는
5번은 프로젝트에 추가한 리스소용 파일을 빌드액션을  resource로 했을때 접근하는 방법이고
3번은 다른 어셈블리(참조추가된)에 있는 리소스에 접근할때 입니다.




 

by 피요히코~ 2010. 8. 25. 02:38
이거저거 하다보면
여러 컨트롤들을 합친 유저컨트롤을 쓸 때가 있습니다.
(뭐 TextBox와 ComboBox를 합친다든지 하는...)
의도에 맞춰서 잘 쓰려면
적절하게 속성도 만들어서 노출시켜야 할꺼고
이벤트도 있어야 할텐데요

간단하게 유저컨트롤에 이벤트를 만들어 보는걸 정리해보겠습니다.
(누군가가 와서 볼꺼라는 생각에 힘들게 존댓말로 글을 쓰지만. 방문자수는 안습. ㅋㅋ)

아주 초 간단하게
그냥 유저컨트롤에 버튼 한개만 (딸랑..)넣어서 작성해보죠
겉보이게는 그냥 버튼과 차이가 없지만
사실 제일 위에는  UserControl이 있고 그 안에 버튼이 있고. Dock이 Fill로 되어 있는겁니다.. ㅋ

이제 이 컨트롤을 사용할때
속성창에서 노출될 이벤트를 만들어줍니다.


[Description("클릭이벤트지롱"), Category("속성이지롱")]
public event EventHandler NewClick;

Description은 속성창에서 해당 속성을 클릭했을때 나오는 설명이고
Category는 해당 속성이 들어있는 카테고리를 설정해 주는겁니다.
그리고 NewClick이라는 새로운 EventHandler를 하나 만들어줍니다.

이렇게 해주고 나중에 이놈을 다른 창에 얹고 클릭해서 속성을 보면



보시다시피 중간에
"속성이지롱" 카테고리에
"NewClick"이라는 이벤트가 보이고
아래쪽에
"클릭이벤트지롱" 이라는 설명이 보입니다. ㅋ

그 다음에는 유저컨트롤 안에서 버튼 클릭이벤트를 만들어준후에
그 이벤트와 새로 만들었던 이벤트핸들러를 연결해 줍니다.
private void button1_Click(object sender, EventArgs e)
{
        MessageBox.Show("클릭");
        OnClick(sender, e);
}

public void OnClick(object sender, EventArgs args) //2
{
        if (NewClick != null)
        {
                Invoke(NewClick, null);
        }
}


button1_Click은 유저컨트롤 안에 있는 버튼의 이벤트고
해당 이벤트 발생시에
OnClick을 호출하도록 했습니다.

OnClick안에서는 이벤트핸들러인 NewClick이 null이 아니면 호출하도록 해줬습니다.

이러면 끝이에요! ㅋ

그리고 다른 컨트롤(기본컨트롤들)처럼 추가해서 NewClick이벤트란을 더블클릭해서 자동으로 이벤트를 만들고
안에 코드를 넣어주면
제대로 잘 돌아갑니다.
public UserControlTest()
{
        InitializeComponent();
        this.ucTest1.NewClick += new EventHandler(ucTest1_NewClick);
}

void ucTest1_NewClick(object sender, EventArgs e) 
{
        MessageBox.Show("여기서클릭");
}


이렇게 하고 실행해서
버튼(처럼 보이는 유저컨트롤)을 클릭하면
"클릭" 과 "여기서클릭" 메시지가 빠방~! 하고 뜹니다.

이걸 순서대로 한번 정리를 해보면요
처음에 유저컨트롤에 있는 버튼을 클릭을 하면
유저컨트롤안에 있는 버튼의 클릭이벤트가 발생해서
button1_Click 이놈이 호출 되겠죠
그리고 "클릭"을 뜨게 한다음에
OnClick을 호출해 줍니다.

OnClick에서는 이벤트핸들러인 NewClick이 null이 아니면
그 놈을 호출해 주는데

보시다 시피
this.ucTest1.NewClick += new EventHandler(ucTest1_NewClick);
이렇게 NewClick 이벤트핸들러에 ucTest1_NewClick 이놈을 += 해줬기 때문에
null이 아닐꺼고
실행이 되겠죠

그러면 ucTest1_NewClick 이놈이 호출되서
"여기서클릭"이 빠방! 하고 또 뜨게 되는겁니다.

음..
전 이렇게 이해했는데
맞을랑가 모르겠네요. ㅋ
by 피요히코~ 2010. 7. 21. 16:36

Virtual와 Abstract는 아직도 많이 헷깔리는 녀석들입니다.

그래서 오늘은 마음먹고 정리...

'-^

기본적으로 Virtual_Abstract 클래스와 이 클래스를 상속받는 SubClass 클래스를 만들어 줍니다.

두 클래스에는 모두 간단한 출력을 해주는 getString() 메서드가 있습니다.

using System;
namespace TestApplication
{
    class Virtual_Abstract
    {
        public Virtual_Abstract() 
        {
            Console.WriteLine("[부모에서 생성]");
        }
 
        public Virtual_Abstract(int i)
        {
            Console.WriteLine(string.Format("[부모에서 인자{0}받아 생성]", i));
        }
 
        public void getString()
        {
            Console.WriteLine("[부모에서 호출]");
        }
    }
 
    class SubClass : Virtual_Abstract
    {
        public SubClass() 
        {
            Console.WriteLine("[자식에서 생성]");
        }
 
        public SubClass(int i)
        {
            Console.WriteLine("[자식에서 인자{0}받아 생성]", i);
        }
 
        public void getString()
        {
            Console.WriteLine("[자식에서 호출]");
        }
    }
 
    class MainClass
    {
        static void Main(string[] args)
        {
            SubClass sc = new SubClass();
            sc.getString();
            Console.WriteLine("--------------");
            SubClass sc2 = new SubClass(11);
            sc2.getString();
            Console.ReadLine();
        }
    }
}

 

 

이걸 실행하면

이렇게 나오네요

 

각 클래스에는 두개의 생성자가 있는데

기본생성자와 int파라미터를 받는 생성자가 있어요

 

출력된걸 보면 일단 부모클래스의 기본 생성자는 무조건 실행되는걸 알수 있죠

그리고 getString()한 결과를 보면 의도(?)대로 출력된걸 알수 있습니다.

 

문제 없이 잘 출력된듯 하지만

경고가 한 개 발생하는데 그 내용은

 

'TestApplication.SubClass.getString()'은(는) 상속된 'TestApplication.Virtual_Abstract.getString()'

멤버를 숨깁니다. 숨기려면 new 키워드를 사용하십시오.

 

아무런 작업없이 자식클래스에서 부모클래스와 같은 메서드를 만들어서 생긴 문제로

경고는 뜨지만 실행은 잘 됩니다.

실행이 되는 이유는 내부적으로(?) 컴파일러가(?) 해당 메서드에 new키워드를 붙였기 때문이구요

실제로 SubClass의 getString()메서드에 new를 붙이면 같은 경고없이 같은 결과를 볼수 있습니다.

 

getString은 자식 클래스에서 재정의된 메서드인데. 메서드를 재정의 할때는 new키워드 말고도 사용할수 있는게 override가 있죠

 

그럼 new와 override의 차이는 뭔까요?

 

new 대신 override를 사용해서 실행해 볼께요

 

그러면 다음과 같은 오류(!)가 발생합니다.

'TestApplication.SubClass.getString()': 상속된 'TestApplication.Virtual_Abstract.getString()' 멤버는

virtual, abstract 또는 override로 표시되지 않았으므로 재정의할 수 없습니다.

 

부모 클래스의 getString메서드가 virtual이나 abstract 메서드가 아니므로 재정의 할수 없다는 거네요.

 

그럼 부모 클래스의 getString메서드를 바꿔볼께요. virtual로 해보겠습니다.

 

 

new키워드를 쓴것과 차이가 없네요.

 

차이가 나는 결과를 보려면

Main클래스에서 getString하는 부분을 바꿔야 합니다.

 

(sc as Virtual_Abstract).getString();

 

그리고 실행을 해보면

new

override

 

getString을 자식클래스 객체에서 호출하는게 아니라

부모 클래스로 업캐스팅후 호출했을때는

두 결과가 틀리게 나옵니다.

 

new를 했을때는 부모클래스의 getString이 호출되고

override했을때는 자식클래스의 getString이 호출됩니다.

 

이유는?

new키워드를 사용해 재정의 하면 자식클래스에서 부모클래스의 해당 메서드를 숨깁니다.

뭐. 관계를 끊는다고 생각하면 될꺼 같아요.. (맞을라나.. -_-ㅋ)

그래서 부모클래스로 업캐스팅해서 getString을 호출하면 부모클래스이 getString이 호출되고

override했을경우에는 getString이 재정의 된 게 있다는걸 알기 때문에 업캐스팅이 되었지만 자식클래스의 getString이 호출되는거라고 생각합니다… -_-v

(MSDN을 참고해보면 getString이 호출될 때 컴파일러가 일단 재정의된 메서드가 있는지를 찾아본다고 하네요.)

 

그럼 이제

해당 메서드를 abstract로 정의해볼께요

메서드를 추상으로 만들면

클래스도 추상클래스여야 합니다.(안그러면 오류가 빠방!)

 

그리고 해당 메서드는 반드시 자식클래스에서 재정의 해줘야 합니다.

그냥 정의하면 안되고 재정의 해줘야 하고

new로는 안되고 override해줘야 합니다.

(안그럼 다 오류나요.. )

 

실행결과는

메서드를 virtual로 해서 override해준것과 같은 결과가 나옵니다.

(업캐스팅해서 호출해도 override한거처럼 나와요)

 

여기서 궁금한거…

아직도 잘 모르겠지만

그렇다면 abstract 메서드와 interface와 뭐가 틀린걸까요..

아….

검색해서 찾아보면

‘is와 as’의 차이로 생각하면 된다고 하는데

 

제 나름은 이렇게 결론냈습니다.

 

Abstract로 정의한 메서드는

종속관계(부모자식관계)에서 자식이 가져야 할 행동(메서드)를 강제하는것이고(무조건 재정의 해야 하니까요)

Interface는

특정 행동들을 강제하는것이다..

-_-ㅋ

 

좀 애매한데..

나름 예를 들어보면

동물(부모클래스)이 있고 멍멍이(자식클래스)와 오리가 있습니다.

이 동물은 모두 걸어댕기죠

하지만 멍멍이가 걷는것과 오리가 걷는건 좀 모양새가 틀립니다.

예를 들어보면

 

class Animal { public void Move() {   }}

 

이런거죠..

근데 자식들이 Move하는게 틀리니까

이놈을

Abstract로 하는겁니다.

 

그렇게 하면

자식들은 무조건 move해야하지만

실제로 move하는 방법은 틀리게 할수 있는거죠

 

하지만 interface로도 같은 일을 할수 있죠

interface Animal
{
    void Move();
}

이런 interface를 만들어서

이놈을 상속받으면 똑 같은 일을 할수 있죠

 

하지만

멍멍이와 오리가 아예 똑 같은 행동을 하는게 있다면

부모클래스에서 공통 부분을 만들어서 상속을 하는게

효과적이겠죠

 

그래서 제가 내린 정의(?)는

Abstract는

자식 클래스가 해야 할걸 정해주는거고

Interface는

해야할걸 정해주는거…

 

이렇게 생각합니다. 크크

 

그래서 interface는 복수상속이 가능하잖아요 크크

 

뭐 또 예를들어보면

Interface로 걷기, 말하기, 등등등 을 정의해놓고

가져다 쓰는거죠

 

아. 이놈은 무조건 걷는건 있어야해.. 하면

걷기 interface를 상속받아서 구현하고 뭐 그런..ㅎㅎ

 

그래서 오늘 이 둘을 합치는걸 알았습니다. -_-(MSDN만쉐..)

 

부모 클래스에서 interface를 상속받아서

그놈을 abstract로 만들어서 자식에서 구현..

이런게 있드라구요

사실 엄청 고민했던거였는데. ㅠ-ㅠ

 

이런걸 오늘 알았따는게 참 부끄럽네요.. 흐흑

 

by 피요히코~ 2010. 7. 20. 16:30
코드를 작성하다 보니
이런경우가 많은거 같더라구요


if(A == "A" || A == "B" || A == "C")
{

}

사실 A라는 변수를 세번 비교를 하는건데...
이게 뭐 크게 불편한건 없지만.
좀 편하게 할수는 없을까 싶어서 생각해보다가
함 만들어봤습니다...(엉망입니다..)

일단 제가 사용한게 string을 비교한거라서
그냥 string에 확장메서드로 만들었구요
(원래는 and나 or에 대해 다 되게 해보려고 했는데 걍 or만 해서..)
orIn이라고 했습니다.(in은 sql에서 사용하는 in 느낌으로......)

public static bool orIn(this string str, List values)
{
      values.RemoveAt(0);
      if (values.Count > 0)
          return str == values[0] || str.orIn(values);
      else
          return false;
}

확장메서드라서 public static이구요..

사용할때는

if (tempStr.Text.orIn(new List {"", "R", "U" }))
{
        //작업
}

이렇게 해줍니다.
파라미터는 List<string>형식이고. (단점은!!) 첫 문자는 필요없는 값이여야 합니다.........

받아온 List<string>의 첫번째 녀석을 계속 없애변서 재귀로 돌리기 땜시...

그리고 또.
제가 알기로는
or가 여러개 있는경우등에서는
첫번째 or에서 값이 true가 나오면 뒤에는 무시한다고 알고 있는데

이 경우에는 끝까지비교를 하기 때문에... 연산이 더 길어져서... 손해가....

그래도
만약 A라는 string변수를 상당히 많은 양의 string값들과 비교할 경우에는 코드양을 조금 줄일수 있지 않을까 싶네요..
(물론.. 모두 or로 연결되어야 합니다...)
by 피요히코~ 2010. 5. 11. 17:04
지난번 메서드 Reflection에 이어서. 이번엔 필드!!!

사실.
reflection으로 메서드를 가져와서 실행시킬수 있다면
당연히 필드도. 비슷하게 핸들링 할수 있을꺼라 생각은 했지만.
(이상하게도!!) 방법을 못찾겠더라구요...

사실 계속
getMember로 가져와서 요고저고 해보니까 안되서 포기했었는데
써야할꺼 같은 일이 생겨서
(써야 한다기 보단.. 코딩양을 좀 줄이려고.... 성능은 신경도 안쓰고...)
다시 찾아보니..
FieldInfo라는게 있더라구요..


사용법은 method랑 거의 비슷합니다.

제가 하려고 했던건
동적으로 field를 가져와서 값을 할당하는거였는데

이렇게 하면 되네요..


FieldInfo fi = this.GetType().GetField("FABRIC_SEQ", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue(this, "할당해줄 값");

이 소스에서는
FABRIC_SEQ라는 필드가. private string으로 선언되어 있습니다. (멤버변수로)
그걸 가져와서
원하는 값으로 할당해 주는건데.

지금 하고 있는게 탭이 상당히 많은 페이지고
탭 마다 셋팅해야 할 값들이 다 달라서.
이렇게 해주니 코드가 많이 줄어드네요..
뭐.. 성능은.. 모르겠네요..

그래도 하나 더 알아냈으니 됐음!
by 피요히코~ 2010. 5. 10. 17:19
지난번에 포스팅 했던 reflection을 사용하다가.
또 알아낸게 있어서 두번째로 다시 포스팅 합니다. ㅋ

메소드를 읽어올때
그냥 메소드 명만 써주면 기본적으로 public 메소드만 가지고 와 집니다.
(전 그래서 메소드를 다 public으로 바꿨.....)

근데 이게
GetMethod에 두번째 파라미터가 있는데. (있는건 알았지만 몰라서 안썼...)
BindingFlags 를 정해주는게 있습니다.
(자세한 내용은 MSDN)

이 파라미터를 지정해 주면
(MSDN말처럼)리플렉션에서 멤버 및 형식 검색이 수행되는 방식과 바인딩을 제어하는 플래그를 지정해 줄수 있습니다.

이렇게 하면 private 메소드도 가져올수 있죠.

그래서 테스트를 해봤습니다.


this.GetType().GetMethod("LF_Save" + tab_Now.Name, BindingFlags.NonPublic);

근데 이렇게 했더니
MethodInfo 가 계속 null이 되더라구요

왜그런가 싶어서 메소드를 다시 public으로 바꾸고
BindingFlags를 Public으로 줘봤는데도...
null... :(

이곳저곳 막 뒤져봤는데 이유를 못찾겠더라구요....

근데역시나..
MSDN을 제대로 안본탓...
MSDN에 이런말이 있더라구요...
Instance 또는 StaticPublic 또는 NonPublic과 함께 지정해야 합니다. 그렇지 않으면 멤버가 반환되지 않습니다.

쿠쿵.. ㅠㅠ

그래서



this.GetType().GetMethod("LF_Save" + tab_Now.Name, BindingFlags.NonPublic | BindingFlags.Instance);

이렇게 하니 잘 되네요... ㅠㅠ
아.....
아......
역시.. 할라면 제대로 하라고..
MSDN을 보려면 제대로 봐야 하네요.....

그래도 하려던게 잘 되서 다행입니다. ㅠㅠ
by 피요히코~ 2010. 5. 7. 11:38
아직 제대로 아는거 같지도 않고.
응용도 못하겠지만.
reflection이라는건 참으로 유용한거 같네요.
이전에 실버라이트쪽에서 reflection으로 페이지 호출하는거 포스팅도 했었는데.
이번엔 간단한 method reflection 예제입니다.

아주 간단한데.
이게 잘 쓰면 코드량을 상당히 줄여줄꺼 같네요...
(이러라고 쓰는게 맞는건 아닌거 같지만. ㅋ)


MethodInfo method = (메소드를 가지고 있는 인스턴스?)GetType().GetMethod("메소드명");
method.Invoke((호출할 인스턴스), (파라미터));

이런식으로 쓰면 됩니다.

만약에 GetMethod에 넣은 메소드명이. 존재하지 않는 메소드라고 하면
method는 null이 되므로
method.Invoke를 호출하기 전에 null 체크를 해주는게 좋겠죠?

그리고
도움말에 나오지만
Invoke의 첫번째 파라미터는 static method의 경우는 무시되고
두번째 파라미터는 Object[] 형식이고
파라미터가 없는 메소드의 경우에는 null입니다.

*추가 주의사항
  전혀 모르고 있다가 MSDN찾아보고 알게된게 있네요..
 GetMethod로 메소드를 찾을때 해당 메소드는 public이여야 합니다... ㅠㅠ 몰라서 한참 헤맸네요. ㅠㅠ
by 피요히코~ 2010. 4. 29. 15:15

Array형식이나 List형식의 데이터는 index를 이용해 해당 데이터에 접근할수 있어요
뭐 예를들자면
List listStr = new List();
listStr.Add("1");
listStr.Add("2");

MessageBox.Show(listStr[1]);

뭐 이런식으로 하면
list의 두번째 데이터인 "2"가 출력되죠.

코딩을 하다보면
내가 원하는 데이터를 따로 담아두기 위해 클래스를 만들기도 합니다.(구조체든지.)

그 클래스에서는 프로퍼티 등을 통해 외부에서 엑세스 할수 있도록 해주죠.

하지만 외부에서 엑세스 하는 변수가 (예를들어) List<T> 형식인 경우

물론 외부에서 그 변수를 그대로 얻어와서
핸들링 할수도 있겠지만.
클래스 자체에서의 작업을 통해
index를 통해 접근 할수도 있습니다.

public 형식 this[int index]
{
     get
    {
        return List[index];
    }
}

뭐 이런식으로 해주면 됩니다.
클래스 외부에서 접근을 해야 하니 당연히 public이겠구요
형식은 뭐. 해당 list의 형식과 맞춰주면 되겠죠.

그리고 이왕이면
Add/Insert/Remove/IndexOf 등의 메서드도 구현해놓는다면
사용할때 더 편리하겠죠?
by 피요히코~ 2010. 4. 26. 14:37

익스플로러에 보면
페이지 열때 페이지를 체크 하는 옵션이 있죠

페이지 내용이 바뀌지 않았을때 어떻게 하느냐인건데

그냥 매번 새로 열껀지 아니면 확인 안하고 캐시에 있는 파일을 쓸껀지

뭐 이런건데

캐시를 사용하면 페이지가 열리는 속도가 향상되겠지만
단점은 바뀐 페이지가 제대로 안보일수가 있다는거..

일반적인 상황이라면 사소할수도 있지만.

암튼

어제오늘
이 문제때문에 고생을 하다가.
캐쉬 문제임을 확인하고
방법은 찾았네요


Response.Expires = 0;
Response.Cache.SetNoStore();
Response.AppendHeader("Pragma", "no-cache");


이 녀석을
Page_Load에 넣어두면
이 페이지는 캐쉬를 안쓰게 되더라구요.
아..
귀찮은녀석.. ㅠ
by 피요히코~ 2010. 1. 14. 12:42
| 1 2 3 4 5 ··· 11 |