GSI

C++ 의 변수를 C#의 프로퍼티 처름 사용하기..

말은 거창하지만 다른건 없다. 해당 값을 입력 받을 경우 다른 변수에 값을 추가 하거나 기타 다른 이벤트를 처리 할때 해당 값에 의존적인 클래스에서 처리 할 수 있다는 부분이다.
m_Val = 100 이렇게 입력 받은 후에 다른 이벤트 처리를 의존 프로퍼티 클래스를 상속받은 클래스에서 처리가 가능하게 만들어 본겁니다. ^^..
사용은 해봐야 알겠지만. 괜찮은 확장이 가능해 질거 같네요..

--라이브러리 클래스--

class CGsiDependencyProperty
{
public:
 CGsiDependencyProperty() {}
 virtual ~CGsiDependencyProperty() {}

 //값이 바뀌게 되면 호출할 수 있도록 바인딩 되는 함수
 virtual void PropertyChanged() {
  int iii = 0;
 };
};

template<class T>
class CGsiDataBind
{
public:
 CGsiDataBind() { m_pDependencyProp = NULL; }
 virtual ~CGsiDataBind() { }

 // int a = ?? 이런 코드가 가능합니다.
 operator T() {
  return m_Data;
 }

 // ?? = 100 이런 코드가 가능합니다.
 T operator = (T value) {
  m_Data = value;

  if(m_pDependencyProp)
   m_pDependencyProp->PropertyChanged();

  return m_Data;
 }

 friend class CGsiDependencyProperty;

 void SetDepend(CGsiDependencyProperty* refOper0 = NULL) {
  m_pDependencyProp = refOper0;
 }

protected:
 T      m_Data;
 CGsiDependencyProperty* m_pDependencyProp;
};

-- 사용법--
해당 변수의 값을 입력 할때 특정 클래스의 함수가 호출 되도록 하는 구조를 취할때
사용하면 됩니다.

호출 되는 함수가 있는 클래스 생성할때 CGsiDependencyProperty을 상속 받아서, virtual로된 함수 PropertyChanged() 를 선언해야합니다

class CDependA : public CGsiDependencyProperty
{
 virtual void PropertyChanged() {
  //값이 바뀌면 호출됨
 };
};

이제 변수를 선언하고 프로퍼티 클래스를 선언해서 연결한 후에
변수를 사용하면 됩니다.

 // 의존 프로퍼티 선언
 CDependA    m_Val0Property;

 // 변수 선언
 CGsiDataBind<int>  m_Val0;
 m_Val0.SetDepend(&m_Val0Property);

 m_Val0 = 100;           // 100을 입력하면 m_Val0Property의 클래스 내부 함수가 호출됩니다.
 int value = m_Val0;    // 해당 값을 일반 변수로 리턴받을 수 있습니다.

Posted by gsi
:

잠깐의 휴식..

내 일상 2007. 11. 16. 18:03 |



이번 주말에 시골을 갈려고 합니다.
상황이 이렇게 되서 애기도 시골에 있고 해서..
넘 보고 싶네요 ^^.. 우리딸..

주말을 통해서 재충전 하고 와야 겠어요 ^^..
모두 주말은 활기차게 보내세요 ..
Posted by gsi
:

MFC DLL 사용하기

C++ 2007. 11. 16. 17:58 |

MFC DLL 사용하기

MFC DLL 프로젝트를 하나 생성한다. ( DllLib 라는 이름으로 프로젝트를 생성한다.)

DllLib.cpp 파일에 해당 하는 함수나 클래스 인스턴스를 하나 만듭니다.
이때 AFX_API_EXPORT를 앞에 붙여서 만들면 됩니다.

AFX_API_EXPORT int Plus(int _first, int _second);
AFX_API_EXPORT void DrawTest(CDC* pDC);

AFX_API_EXPORT int Plus(int _first, int _second)
{
 _first += m_Test.value;

    return (_first+_second);
}

AFX_API_EXPORT void DrawTest(CDC* pDC)
{
 pDC->MoveTo(10, 10);
 pDC->LineTo(100, 100);
}

이렇게 만든 후에 MFC Dialog 베이스로 프로그램을 하나 만들어서 테스트를 해봅니다.
(DllTestView 라는 이름으로 프로젝트를 생성한다.)

원하는 코드에서 해당 함수를 호출 하기 위해서 DllLib에서 만들어 놓았던 함수들을
선언해 줍니다.

AFX_API_IMPORT int Plus(int _first, int _second);
AFX_API_IMPORT void DrawTest(CDC* pDC);

이후에 사용은 아래와 같이 하시면 됩니다.

void CDllTestViewDlg::OnPaint()
{
......
 {
  CPaintDC dc(this);
  DrawTest(&dc);        // DC를 넘겨서 라인을 찍는 함수 테스트
  CDialog::OnPaint();
 }
}

// 두개의 에디터 박스에서 값을 int 형으로 받아서 합계를 내주는 함수 사용
void CDllTestViewDlg::OnBnClickedButton1()
{
 UpdateData(TRUE);
 m_Sum = Plus(m_Left, m_Right);
 UpdateData(FALSE);
}

요즘은 프로젝트가 대형화 되고, 한사람이 짜는 프로젝트가 많이 없다 보니
슬슬 DLL을 써야 할거 같다.

Posted by gsi
:

데이터 바인딩#1 - 기본
데이터 바인딩#2 - Binding Mode
데이터바인딩#3 - DataContext
▶데이터 바인딩#4 - TextBox vs Run
데이터 바인딩#5 - FrameWorkElement Demo
데이터 바인딩#6 - IValueConverter


소스 정보를 사용해서 타겟에 적용할때 텍스트로 원하는 형태의 문자열로 만들어서 하고 싶을때가 있다.
아래의 예제를 보자.

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" Name="window">

    <StackPanel Orientation="Horizontal"
                HorizontalAlignment="Center" VerticalAlignment="Center"
                DataContext="{Binding ElementName=scroll}" Name="stackpanel">
        <TextBlock Text="{Binding ElementName=window, Path=ActualWidth}" />
        <TextBlock Text=" &#x00D7;" />
        <TextBlock Text="{Binding ElementName=window, Path=ActualHeight}" />
        <TextBlock Text=" Device independent units"/>
    </StackPanel>

</Window>

실행해 보면 300 x 300 device independent units 라는 글자를 볼 수 있다.
TextBlock를 여러개 써서 하는거 자체가 조금 어울리지 않아 보인다. 그래서 Run 을 사용하는 코드를 적용하게 되면 조금더 코드가 깔끔해지게 된다.

아래의 코드는 TextBlock로 이루어진 부분을 Run으로 처리한 내용이다.

        <TextBlock>
            <Run Text="{Binding ElementName=window, Path=ActualWidth}" />
            <Run Text=" &#x00D7;" />
            <Run Text="{Binding ElementName=window, Path=ActualHeight}" />
            <Run Text=" Device independent units" />
        </TextBlock>

하지만 이 코드를 쓰게 되면 아래와 같은 에러 코드를 보게 된다.
Error 1 A 'Binding' cannot be set on the 'Text' property of type 'Run'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject. D:\temp4\WpfApplication1\WpfApplication1\Window1.xaml 15 24 WpfApplication1

이 에러가 나는 이유는 TextBlock에 정의된 Text 프로퍼티는 TextProperty라는 의존 프로퍼티에 의해 지원되지만 Run에는 정의 되어 있지 않아서 있다.
즉, 이 이유는 데이터 바인딩의 타깃은 반드시 의존 프로퍼티가 되어야 하는 것이 이유이다.

의존 프로퍼티를 적용한 가장큰 이점은 데이터 바인딩이며, 의존 프로퍼티 시스템은 내부에 통보 장치가 구현되어 있다는 것이다. 바인딩 소스가 의존 프로퍼티가 될 필요는 없지만 의존 프로퍼티일 경우에 유리한 상황이 되는 것이다.

FrameworkElement를 상속 받아서 작성한 clr 객체가 DependencyProperty를 정의 하게 되면서 데이터 바인딩 통지 메시지를 받는 예제를 보여 드리겠습니다.

참고 ^^
본 내용은 "찰스페졸드의 WPF"의 내용을 이해 하고 나름 생각과 같이 정리한 겁니다.
제제가 가해질 경우 바로 삭제하도록 하겠습니다. ^^;
Posted by gsi
:

가끔 요즘 나오는 기술들을 보다 보면 데이터 바인딩에 대한 내용이 잘 구현되어있는거 같다. 물론 이해는 100% 되지 않지만 말이다.

그래서 C++에서 나름대로 사용하면 이런 형태는 어떨까 해서 하나 만들어 봤다. ^^
조금더 다듬어서 일부 기능은 이것을 사용해도 될거 같다.

사용되는 구조는 데이터를 가지고 있는 객체를 CContain 클래스 처름 구헌한다고
가정을 해보면 CDataBind 클래스와 연결후에 CDataBind의 객체만 SetValue 하면 된다.
이때 CContain 인스턴서의 PropertyChanged()가 자동으로호출 될 수도 있다.

이것과 다르게 함수포인터를 연동하는 부분도 추가를 해봤다. 클래스 내부의 함수가
함수 포인터로 하기에는 조금 몇가지 제약사항이 있기 때문에 전역 함수를 포인터와
연동하고 값이 바뀌게 되면 해당 함수가 호출 되는 구조를 취하게 된다.

혹.. 필요하신분 있으시면 요청시 설명해드릴게요 ^^
혹.. 좋은 의견 있음 코멘트 부탁 해요. ^^

Posted by gsi
:

데이터 바인딩#1 - 기본
데이터 바인딩#2 - Binding Mode
▶데이터바인딩#3 - DataContext
데이터 바인딩#4 - TextBox vs Run
데이터 바인딩#5 - FrameWorkElement Demo
데이터 바인딩#6 - IValueConverter

바인딩 소스 객체를 다른 방법인 FrameworkElement 에 정의된 DataContext를 사용했다.

    <StackPanel >
        <ScrollBar Name="scroll" Orientation="Horizontal" Margin="24"
                    Minimum="1" Maximum="100"
                    LargeChange="10" SmallChange="1" />
        <Label HorizontalAlignment="Center"
                    DataContext="{Binding ElementName=scroll}"
                    Content="{Binding Path=Value}" />
    </StackPanel>

기존의 Label에
Content="{Binding ElementName=scroll, Path=Value}"로 작성했다면,
위의 코드는 DataContext로 분리 되어 두개로 구성되어 있다.
하지만 Datacontext로 했다고 해서 특별히 달라지는 건 없다. 그런데 DataContext가 유용할 때가 있다. 즉, DataContext는 엘리먼트 트리를 통해 상속된다는 것이다. 하나의 엘리먼트에 DataContext를 사용해서 바인딩을 설정하고 자식 엘리먼트에 동일하게 적용되게 되기 때문이다.

아래의 예제를 보자.

    <StackPanel DataContext="{Binding ElementName=scroll}">
        <ScrollBar Name="scroll" Orientation="Horizontal" Margin="24"
                    Minimum="1" Maximum="100"
                    LargeChange="10" SmallChange="1" />
        <Label HorizontalAlignment="Center"
                    Content="{Binding Path=Value, Mode=OneWay}" />
        <Button HorizontalAlignment="Center" Margin="24"
                FontSize="{Binding Path=Value, Mode=OneWay}">
            Son Byoung Uk
        </Button>
    </StackPanel>

사용자 삽입 이미지

DataContext는 StackPanel에 한번 설정되고 Label과 Button은 ScrollBar와 바운딩 되었습니다. ScrollBar를 움직이면 Label의 값이 바뀌고 Button의 FontSize와 바인딩 되면서 글자 크기가 바뀌는 것을 볼 수 있습니다.

참고 ^^
본 내용은 "찰스페졸드의 WPF"의 내용을 이해 하고 나름 생각과 같이 정리한 겁니다.
제제가 가해질 경우 바로 삭제하도록 하겠습니다. ^^;
Posted by gsi
:

데이터 바인딩#1 - 기본
▶데이터 바인딩#2 - Binding Mode
데이터바인딩#3 - DataContext
데이터 바인딩#4 - TextBox vs Run
데이터 바인딩#5 - FrameWorkElement Demo
데이터 바인딩#6 - IValueConverter


Binding 정의가 있는 컨트롤이나 엘리먼트는 항상 바인딩의 타깃이 된다. 바인딩 타깃은 DependencyObject로부터 상속되며 바인딩이 설정되는 프로퍼티는 반드시 의존 프로퍼티의 지원을 받아야 한다.
그래서 Label인 경우 DenpendencyObject 타입의 정적 publid필드인 ContentProperty가 존재 하게 된다. (내부적으로 ^^)

바인딩의 코드를 C#에서 처리한 예제를 보면 알 수 있다.

ScrollBar > scroll
Label > lbl
이라고 가정한다.

Binding bind = new Binding();
bind.Source = scroll;
bind.Path = new PropertyPath(ScrollBar.ValueProperty);
lbl.SetBinding(Label.content, bind);

여기서 바인딩 타깃은 SetBinding의 메소드를 통해서 호출되게 된다. 이 메소드는 FrameworkElement에서 정의 되었고 DependencyProperty인자를 알수 있습니다.

이제 바인딩에 사용되는 Mode에 대해서 살펴 보겠습니다.
바인딩의 Mode를 보게 되면, OneWay, TwoWay, OneTime, OneWayToSource로 나열할 수 있습니다.

기본적인 형태는 아래와 같습니다.

Content="{Binding ElementName=scroll, Path=Value, Mode=OneWay}"

여기서 Mode 프로퍼티를 설정하는 것은 Path 프로퍼티를 설정하는 것과 같이 콤마로 구분됩니다.

Content="{Binding ElementName=scroll, Path=Value, Mode=TwoWay}"

이전의 코드에서 보게 되면 OneWay, TwoWay 는 동일하지만 실제로는 Label의 Content 프로퍼티의 변화도 ScrollBar의 Value프로퍼티에 반영됩니다.

Content="{Binding ElementName=scroll, Path=Value, Mode=OneTime}"

OneTime 모드의 경우는 타깃이 소스로부터 초기화는 되지만 소스의 변화에 반응하지 않습니다. 즉, 한번만 초기화 되고 더이상 되지 않습니다.

Content="{Binding ElementName=scroll, Path=Value, Mode=OneWayToSource}"

이것은 일반적으로 소스와 타깃의 의미에 반대 되는 행동을 하게 됩니다. 다시 말해서 과녁이 화살을 향해서 간 다음에 꽂히는 것과 같습니다.
이 경우는 타깃은 소스를 갱신하게 되는데요. 이전의 코드에서는 Label은 ScrollBar에 건네줄 숫자 형태의 데이터가 없기 때문에 Label은 비어 있고 ScrollBar를 움직여도 반응이 없게 됩니다.

하지만 OneWayToSource가 유용할 때가 있습니다. 바로 두 프로퍼티를 바인딩할 때 타깃 프로퍼티가 의존 프로퍼티의 지원을 받지 못하지만 소스는 지원받는 경우라면 소스에 바인딩을 걸고 Mode를 OneWayToSource로 설정하는 것으로 해결할 수 있습니다.
아래의 소스를 보시면 알 수 있습니다.

    <StackPanel>
        <ScrollBar Orientation="Horizontal" Margin="24"
                Maximum="100" LargeChange="10" SmallChange="1"
                Value="{Binding ElementName=lbl, Path=Content}"/>
        <Label Name="lbl" Content="50" HorizontalAlignment="Center" />
    </StackPanel>

사용자 삽입 이미지

위의 코드가 되면 Label은 소스가 되고 ScrollBar는 타깃이 되게 됩니다.
Label은 50으로 Content를 설정하였고, ScrollBar는 가운데 있게 됩니다. ScrollBar를 움직이면 Label도 같이 움직이는 것을 알 수 있습니다. 이 부분은 Mode가 기본적으로 TwoWay로 설정되어 있기 때문입니다.
하지만 TwoWay를 OneWay 또는 OneTime 로 하게 되면 동작하지 않습니다.

조금 다르게 아래의 코드를 봅시다.

Value="{Binding ElementName=lbl, Path=Content, Mode=OneWayToSource}"

모드는 OneWayToSource로 하게 되면 ScrollBar가 Label 소스를 제어 하게 됩니다. Label은 ScrollBar의 Value을 사용해서 50이 0으로 초기화가 되며ScrollBar를 움직이면 Label이 움직이게 되는 것을 확인할 수 있습니다.

기본 바인딩 Mode는 바인딩이 정의되어 있는 곳의 프로퍼티에 의해 제어되게 된다. ScrollBar에서  Value 프로퍼티의 기본값이 TwoWay 바인딩 모드로 설정되어 있어야 한다.
ScrollBar의 의존 프로퍼티인 ValueProperty는 BindsTwoWayByDefault 프로퍼티가 true인 FrameworkPropertyMetadata가 필요하게 되는 것이다. (이것은 속에 있나 봅니다. ^^)

Mode 프로퍼티는 바인딩의 가장 중요한 컴포넌트 중의 하나입니다. 알맞는 Mode를 설정하는 것이 중요합니다. ^^

참고 ^^
본 내용은 "찰스페졸드의 WPF"의 내용을 이해 하고 나름 생각과 같이 정리한 겁니다.
제제가 가해질 경우 바로 삭제하도록 하겠습니다. ^^;
Posted by gsi
:

데이터 바인딩#1 - 기본

WPF 2007. 11. 16. 10:04 |

▶데이터 바인딩#1 - 기본
데이터 바인딩#2 - Binding Mode
데이터바인딩#3 - DataContext
데이터 바인딩#4 - TextBox vs Run
데이터 바인딩#5 - FrameWorkElement Demo
데이터 바인딩#6 - IValueConverter

이번 내용은 기본 바인딩에 대해서 설명 합니다.
ScrollBar와 Label 연동 부분으로 설명합니다.

데이터 바인딩은 컨트롤과 엘리먼트의 데이터 연결하는 것을 말한다.
데이터 바인딩은 CheckBox 컨트롤을 불리언 변수에 연결하는 것과 같은 간단한 방법 부터 데이터 베이스와 데이터 엔터리 패널을 연결하는 것처름 복잡해질 수 있다.

데이터 바인딩은 소스(Source)와 타깃(target)가 필요하다.
일반적으로 소스는 데이터, 타깃은 컨트롤을 의미 한다. 하지만 컨트롤의 값을 데이터로 전달할 경우는 소스가 타깃이 되는 경우가 있다.

가장간단하게 데이터 바인딩을 생각해 보면 ScrollBar의 Value 프로퍼티를 보여주기 위한 Label 컨트롤을 생각해 볼 수 있다.

// 바인딩 소스
<ScrollBar Name="scroll" Orientation="Horizontal" Margin="20" Maximum="100" LargetChange="10" SmallChange="1" />
// 바인딩 타깃
<Label HorizontalAlignment="Center" Content="{Binding ElementName=scroll, Path=Value}"/>

바인딩 자체는 언제나 타깃 내에서 생성된다.
Content="{Binding ElementName=scroll, Path=Value}"

중괄호 내에 Binding가 정의 되어 있고, Binding 클래스의 프로퍼티중 ElementName, Path가 정의에 포함되게 된다. 즉, ElementName에 ScrollBar의 Name가 포함되고 Path에 ScrollBar의 Value가 포함되게 된다.
여기서 보게 되면 기존의 xaml 코드와 다르게 Binding의 코드는 내부에 "" 이것으로 묶지를 않았다. 솔직히 이 부분은 나도 아직도 애메하다. ^^
위의 코드를 조금더 풀어 쓰게 되면 아래와 같이 된다.

<Label HorizontalAlignment="Center">
   <Label.Content>
      <Binding ElementName="scroll" Path="Value" />
   </Label.Content>
</Label>

위의 코드 보다는 조금더 보기는 편한거 같다. 인텔리센서도 먹으니 편한듯 보이고 두개의 연관성을 고려해서 코드 짜는 법을 익혀야 할거 같다.

위의 코드로 구성되는 프로그램은 아래와 같습니다.
사용자 삽입 이미지

다음 내용은 Binding에 대해서 조금더 상세한 내용을 정리 하겠습니다.

참고 ^^
본 내용은 "찰스페졸드의 WPF"의 내용을 이해 하고 나름 생각과 같이 정리한 겁니다.
제제가 가해질 경우 바로 삭제하도록 하겠습니다. ^^;
Posted by gsi
:

vector를 사용해서 객체를 저장할때 포인터 형으로 하게 되면
메모리 누수를 막기 위해서 객체를 항상 Delete 해줘야 한다.
솔직히 매번 Add, Delete, DeleteAll 등을 해줘야 하는 불편함이 전(??) 있었다. ^^
그래서 템플릿으로 하나 만들었다.
for-each 이건.. 왜 안되는지 ^^.. 암튼.. 현재걸로 조금 우선 사용해보자.

// 사용법 //
CGsiV<CTest> VectorArray;
VectorArray.Add(new CTest());
int size = VectorArray.GetVector()->size();

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// CGsiV
template <class T>
class CGsiV
{
public:
 CGsiV() {
  m_v.clear();
 }

 virtual ~CGsiV() {
  DeleteAll();
 }

 // Add
 void Add(T* t) {
  m_v.push_back(t);
 }

 // Delete
 bool Delete(T* t) {
  T* p;
  vector<T*>::iterator iter;
  for(iter = m_v.begin(); iter != m_v.end(); ++iter) {
   p = (*iter);
   if(p != NULL && p == t) {
    delete p;
    p = NULL;
    m_v.erase(iter);
    return true;
   }
  }
  return false;
 }

 // DeleteAll
 void DeleteAll() {
  T* p;
  vector<T*>::iterator iter;
  for(iter = m_v.begin(); iter != m_v.end(); iter++) {
   p = (*iter);
   if(p != NULL) {
    delete p;
    p = NULL;
   }
  }
  m_v.clear();
 }

 //GetVector
 vector<T*>* GetVector() { return &m_v; }

protected:
 vector<T*> m_v;
};

Posted by gsi
:

DB를 잘 알지 못하는 상황에서 VS2008 beta 2를 사용하다 보면, 몇가지 문제에 부딫히게 됩니다.
ADO.NET를 사용하게 되면 DB를 접근해서 데이터를 가져 오는 상황이 여러개의 라인으로 처리 해야 합니다.
물론 그것을 이용하면 쉬울지도 모르겠습니다.
하지만 VS2008 beta 2 를 사용하다 보면 DataSet를 생성하게 되면 몇개의 파일이 생깁니다.
사용자 삽입 이미지
예를 들어서 Database1DataSet로 생성했다고 하면 아래와 같은 파일이 생깁니다.

이것을 어떻게 사용하냐.. 빌더를 하고 나면 ToolBox에 컨트롤이 몇개가 생기게 됩니다.


사용자 삽입 이미지
이것을 WindowForm에 추가를 시킵니다.







몰론 이전에 DB Table를 하나 만들어야 됩니다.
아래와 같이 간단하게 하나 만들어서 추가해 보겠습니다.
DataSet의 Query 문까지 같이 ...
사용자 삽입 이미지
아래의 화면에서 xsd 쪽으로 Test01의 Table를 드래그 해서 놓으면 테이블이 화면에
생성 됩니다.
사용자 삽입 이미지
이 화면은 Fill,GetData()라는 쿼리 문이 자동으로 생성 되게 되는데요. 그림과 같이 ScalarQuery(@userid) 라는 항목을 같이 넣어 봤습니다.

ScalarQuery(@userid) 해당 아이디가 들어 왔을때 string형태로 원하는 테이블을 뽑아낼 수 있습니다.

여기서는 로그인 폼으로 사용하는 것이라서 userid가 들어 오면 pass를 뽑아 주도록 해보았습니다.
사용자 삽입 이미지


이제 형태가 다 갖추어 졌으니. 아래와 같은 코딩으로 사용하면 됩니다.

string passStr = test01TableAdapter1.ScalarQuery("gsi451").ToString();

여기서 test01TableAdapter1은 xsd 파일을 통해서 생성된 컨트롤 이며, WinForm에 추가한 내용입니다.

내용이 동영상으로 올려야 좋을거 같은데요.
문서상으로 할려니 순서가 조금 뒤죽박죽이네요..
이 부분에 대한 궁금한 내용은 연락 주시면. 답변 드릴께요.

그럼.. 수고하세요.

Posted by gsi
:

사용자 삽입 이미지

Blend에서 처리한 Animation의 정보중에서 Value 값을 바꾸는 곳을 테스트한
데모 입니다.

관련소스
Posted by gsi
:

Blend를 사용해서 Animation을 작성하다 보면 Blend에서 작성한 코드만 가지고 안될때가 많다. 코드 중간 중간 실시간적으로 받은 데이터의 값을 에니메이션 Value에 추가해서 사용해야 할때가 많아 진다.

이럴 경우 코드 비하인드에서 스토리 보드 부터 다 짜게 되면야.
값 접근하는게 어렵지는 않다. 하지만 에니메이션 정보를 코드로 다 짜준다는건 캐 노가다거나 거의 비효율적인 작업이 될 것이다. 그래서 몇가지 예제를 찾아 봤는데.

다른 방법이 하나 있긴 하다 공도님 사이트에서 본것 ^^..
이것 > http://gongdo.tistory.com/110

하지만 그것도 좀 그렇다. 왠지 작업량이 복잡해 지고 불편하다.

그래서 내부 구조를 조금씩 보면서 아래와 같은 접근 방법을 사용하였다.

<Storyboard x:Key="Timeline1">
 <DoubleAnimationUsingKeyFrames x:Name="TestAni1" BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
  <SplineDoubleKeyFrame x:Name="TestSpline1" KeyTime="00:00:00" Value="0"/>
  <SplineDoubleKeyFrame x:Name="TestSpline2" KeyTime="00:00:01" Value="192"/>
 </DoubleAnimationUsingKeyFrames>
 <DoubleAnimationUsingKeyFrames x:Name="TestAni2" BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
  <SplineDoubleKeyFrame x:Name="TestSpline3" KeyTime="00:00:00" Value="0"/>
  <SplineDoubleKeyFrame x:Name="TestSpline4" KeyTime="00:00:01" Value="62.206"/>
 </DoubleAnimationUsingKeyFrames>
</Storyboard>

위의 코드도 결국 cs 파일에서 하는거 처름 다 추가 되는거라고 생각하고.
아래와 같이 분해 해보았다.

이런 XAML 코드가 있다고 하고 192라는 값을 코드 중간에 바꾸고자 할때
아래와 같이 하면 접근이 되는 것을 확인 하였다.

// 스토리 보드를 가져 온다.
Storyboard st = (Storyboard)this.FindResource("Timeline1");
// 스토리 보드의 내부 타임 라인 그룹정보를 가져 온다.
TimelineCollection tgroup = (TimelineCollection)st.Children;
// TimelineCollection 안에 있는 객체 하나를 가져 온다.
// 근데 여기서 int형 배열 정보만 받는다. 그럼 내가 몇번째 것을 제어 하고 싶은지
// 알아야 할거 같다.
DoubleAnimationUsingKeyFrames dAniFrame = (DoubleAnimationUsingKeyFrames)tgroup[0];
// SplineDoubleKeyFrame  정보를 가져 오기 위해서
// DoubleKeyFrameCollection 의 정보를 가져 온다.
DoubleKeyFrameCollection dAniFrameGroup = (DoubleKeyFrameCollection)dAniFrame.KeyFrames;
// SplineDoubleKeyFrame  정보를 가져 온다.
SplineDoubleKeyFrame spAniFrame = (SplineDoubleKeyFrame)dAniFrameGroup[1];
// Value 값을 조정할 수 있게 된다.
spAniFrame.Value = 500;

코드 량은 좀 되는거 같아도 접근을 할 수 있는거 같은데요.
사실 이거 말고 다른게 있을듯도 한데.. ms가 이거 만들면서 이런거 고민했을텐데.
사실 다른건 아직 방법을 찾지 못했네요.

혹시 아시면 코멘트 부탁해요.

Posted by gsi
:

사용자 삽입 이미지
돈많은 일본의 뽀대나는 건담
 
사용자 삽입 이미지
우리나라의 절약정신이 묻어나는 풋풋한? 건담

출처 : http://cafe.naver.com/latalesia/12434
Posted by gsi
:

사용자 삽입 이미지
아마도 지금 나한테 필요한건 4, 5개 정도 공부 하고 있는 프로그램의 연관
고리인듯 하다.

여러개의 프로그래밍 언어를 공부 해야 내가 구현하고자 하는 것을 진행할 수 있으니.
분명 공부는 해야 하고 순서도 필요하다.

하지마 중간 중간 산출물을 만들어 내고 그것을 통해서 통합 되어 가는 과정이
필요할듯 한데..

아무래도 지금 내가 필요한건 계획적인 진행인듯 하다.

잘해보자.. gsi .. 화팅!!...

이번주 부터는 조금더 재미 있어 질듯 하다..
Posted by gsi
:

사용자 삽입 이미지

프로그램을 하다 보면 마음 먹은대로 빨리빨리 되지 않는다.
가끔 느끼지만 아.. 난 이것도 모른단 말인가..

지금 공부 하고 있는 C#, WPF, Silverlight, asp.net Web Service 등에 대한
나의 견해다.
모르는 부분을 새롭게 공부하면서, 마음은 벌써 지금 프로그램 수백개는 짜고 있지만.
사실상 맘 먹은 것을 짤려고 하면.. 처음 부터 막힌다.

지금까지 몇번이나 그래 왔는지.. 그때 마다 느끼는건.
그래 기초가 부족해.. 다시 공부 하자..
이런 생각에 딜레마에 빠지곤 한다.

그래도 뭐.. 무언가를 새롭게 배워 나가며, 발전해 나가는건
좋은 거니까.

조금씩 성장해 가는 내 모습에.. 보기가 좋아진다.

우리 나라에서 10등 안에 드는 프로그래머는 되봐야 좀 직성에 풀릴듯 하다.

공부를 못해서 10등에 들어 보지도 못했지만 밀이다.. ^^

미친듯이.. 해보자..  화이팅!!!
Posted by gsi
: