퇴근5분전

# 숫자 포맷 지원하는 텍스트 박스

# 빨간 테두리는 일시적인 효과처리. ( 유효성 체크 후 표시후 원래대로 돌아갈때 사용 )

 

굿센에서 WPF 하면서 항상 부족하다고 느꼈던건 숫자 관련 텍스트박스.

요구사항은 현업에 따라 많았으나...  여러가지 방법들로 만들어 사용해봤었음.

 

이번에 내용들을 정리하며 새로 만들어 샘플로 만들어보았음.

또한 유효성 체크를 마치고 탈락된 컨트롤들에 대한 효과처리가 없어서 그에 대한 효과처리를 진행하기위해

애니메이션 효과를 이용하여 살짝 효과를 주고 다시 원래대로 복구되는 메서드 하나를 만듬.

 

바인딩 테스트도 해보았음.

<ntxt:NumberTextBox x:Name="txtnum" HorizontalContentAlignment="Stretch" Margin="3" VerticalAlignment="Center" Value="{Binding Sum, Mode=TwoWay}" Format="N3" ></ntxt:NumberTextBox>

 

 

 

  뭐라고 써야 좋을까??? 딱히... 떠오르지는 않네?

 

다양한 컨트롤들의 이벤트들이 즉시 호출되지 않고 일정 시간내에 다른 컨트롤들의 이벤트발생이 없으면

 

지정된 메서드를 호출하는 형태를 만들었다.

 

버튼1, 버튼2, 라디오1, 라디오2 가 있을때

 

버튼들을 1초내에 클릭 또는 체크시 지정된 메서드를 바로 호출하는 것이 아니고 기다린다!

 

1초내에 다른 버튼의 이벤트가 발생하면 계속 기다려주다가 일정 시간동안 이벤트가 없으면 지정된 메서드를 호출한다.

 

이게 필요한곳이 있어서 샘플로 만들어봤을뿐...  다른 개발자분이 맡아서 진행하는 부분이라 ...

 

 

5회 연속 이벤트를 여기저기 컨트롤을 건드려 이벤트를 발생하였다.

 

시간이 되어 3125이벤트 발생 결과를 뿌려주고 있다.

 

프로그래스바는 100%가 되면 이벤트 호출이 되는 시점을 직접 볼 수 있도록 붙여봤다.

소스 (hidden)!

 

 

 플젝중에 난간함 상황이 생겼다.

금액과 관련된 TextBox Field에 TextBox를 넣었기에 숫자이외에 영어 한글 모두 입력이 되는 부분..

물론 개발프레임웍에 숫자관련 컨트롤이 사용자정의를 통해 만들어져 있다. 사용하지 않는 분위기...?

 

 기존 디자인에 거의 모두 Textbox가 되어 있기에 이것을 이용해서 숫자이외에 차단!!

이건 의외로 간단히 처리가 되었고...

  PreviewKeyDown을 이용해서 필터링을 거쳤다.

 

다만 문득 떠오르는게...

 

DB의 데이타 타입과 C#의 데이타 타입이 허용범위가 다르다는 것이었는데???

 

Numeric( 5, 3 ) 를 DB에 넣으면서... !!!!

 

C#에서 단순히 double로 처리해서 파라미터 넘겨주면??

 

Numeric( 18, 2 ) 에서 ... Decimal로 처리는 했는데...

 

단순 데이타 처리를 저렇게 한다고 해도... 그럼.. TextBox의 입력은???

 

음.. 그래서 생각한게 maxLength를 지정하고 scale이 있으면 소숫점 자리와 마이너스표시 자리수 까지 maxLength로 잡아주었다.

 

Numeric( 5, 3 )의 DB에 준비가 되었을때...

 

입력은 MaxLength = 7이 되었다.

 

그리고 계산해서 최대값을 보니 99.999 최소값은 -99.999 ,  MsSql에서 직접 테스트 해보니 100은 못넣더랑...

 

그래서 입력은 실제로 9999999 까지 입력을 받을 수 있다.

 

고럼... keydown할때 다음 값을? 계산해서 범위에 맞지 않으면 cancel 처리 하려고 했는데...

 

배보다 배꼽이 되겠다..

 

그래서 생각한게 그냥 저장전에 유효성체크를 범위를 포함해서 한번 더 하자... 였다.

 

 tb1.EventAttachedForNumericInputFormat((e) => { }, 5, 3); // Numeric( 5, 3 )을 범위로 입력가능 -99.999 ~ 99.999
 tb2.EventAttachedForNumericInputFormat((e) => { }, "N0", 0, 10); // 0~10 까지 범위를 가진 2자리 입력가능 0 ~ 10

 

이렇게 해당 텍스트박스에 확장메서드로 구현해두면... 숫자 포멧도 되고! 범위도 체크가 되고...

 

저장전 유효성 체크는

 

 // 0~100범위 내에 있으므로 pass

 if (TextBoxWPF_Ex.IsCheckNumberRange("99", 0m, 100m) == false) {
         MessageBox.Show("허용범위 밖입니다.");
 }

 

 //-99.999~99.999 범위 밖이므로 alert

 if (TextBoxWPF_Ex.IsCheckNumberRange("100", 5, 3) == false)
 {
        MessageBox.Show("허용범위 밖입니다.");
 }

 

 // pass

 if (TextBoxWPF_Ex.IsCheckNumberRange("99", (decimal)int.MinValue, (decimal)int.MaxValue) == false)
 {
        MessageBox.Show("허용범위 밖입니다.");
 }

 

 여기서 한가지 맹점.이...   int, int 타입으로 prev, scale을 받고, decimal , decimal로 min, max를 받아서

하나의 메서드를 오버로드 시켰더니...

 

 int.MinValue와 int.MaxValue가 사용되는 db에서의 int의 범위에 대하여 넣을땐! 위처럼 decimal로 치환을 해야된다..

 

 안그러면 prev가 int.minValue 만큼.. scale이 int.MaxValue 만큼 잡아서 OutOfMemory 메세지를 보게 된다.

 

너무 급조해서 앞으로 좀더 고쳐봐야지... 쉽게...  winform용도 하나 만들어놔야징.

 

##### 추가

 

입력 숫자 자체를 범위에서 제한 하도록 수정!!

 

                    string x = txt.Text;
                    string xx = x.Remove(txt.CaretIndex, txt.SelectionLength);
                    if (e.Key == Key.Back && txt.SelectionLength <= 0 && (txt.CaretIndex - 1 >= 0))
                    {
                        // 1 char 삭제
                        xx = x.Remove(txt.CaretIndex - 1, 1);
                    }
                    else if (e.Key == Key.Delete && (txt.CaretIndex) < txt.Text.Length)
                    {
                        // 1 char 삭제
                        xx = x.Remove(txt.CaretIndex, 1);
                    }
                    else
                        xx = xx.Insert(txt.CaretIndex, GetChar(e.Key));

                    e.Handled = !IsCheckNumberRange(xx, minValue, maxValue);

 

이렇게 하면 입력된 숫자를 포함해서 범위를 체크할수 있다.

 

key처리전에 N0 포멧일경우 소숫점(.) 에 대한 예외 처리를 해주면 깔끔해진다.

 

또 처리 할 것이 남았다. 입력범위 밖에 숫자를 입력했을 경우 어떻게 알려줄것인가???

 

툴팁? Alert? 색상?...     

 


http://social.msdn.microsoft.com/forums/en-US/wpf/thread/a80296be-e810-449a-843e-bba4a31c1b0e/ 

KeyEventArgs enter = new KeyEventArgs( Keyboard.PrimaryDevice , Keyboard.PrimaryDevice.ActiveSource , 0, Key.Enter );
enter.RoutedEvent = Keyboard.KeyDownEvent;
enter.Source = 대상객체;
InputManager.Current.ProcessInput(enter);



WPF용 플렉스 그리드에서 콤보박스형태로 데이타를 나타나게 하려면...

해당 컬럼에 ValueConverter에 
1.  new ColumnValueConvert(    [] 타입 , false );
2.  new ColumnValueConvert(  Dictionary  );
   ? 여기서 문제가 발생

  코드값 Y  , Name 값 Y인경우... 
 dic["Y" ] = "Y"; 로 해서 바인딩 시켰을 시 문제가 생긴다.

이를 해결하기 위한 방법을 아래 설명하였다.

( 삽질 신공으로 투자한 시간은 2일정도 된것 같음.. )
덕분에 바인딩을 모두 다시 공부했다...

/********************************************************************************************************

플렉스 그리드에서 기본 제공되는 컨버터로는 해결이 안된다.
예제 샘플을 보면 Dictionary로 선언해서 객체에서 받아서 넘겨주면
Key를 int로 검색하여 코드의 경우 문자열을 코드로 사용하는 경우
문제시 된다. : 예외로 지정한 캐스팅이 어쩌고 저쩌고...

이를 해결하기 위한 방법은 아래처럼 하면 된다.

1. AutoGenerateColumns  = false를 준다. ( true일경우 똑같은 컬럼들이 새로 생성된다 )
2. ItemSource 속성에 {Binding} 설정
3. DataContext에 데이타 테이블을 넘겨준다.
4. 컬럼.Binding = new Binding( Path명 ); 으로 설정해준다.
5. 컬럼.ValueConverter 에 새로 만든 UsedColumnValueConvert를 넘겨주자.
 : 컨버터에는 코드키와 값을 셋팅한 Dictionary<object, string>으로 구성해서 넘겨준다.

**********************************************************************************************************/
.cs 


    DataTable dt = new DataTable();

                dt.Columns.Add("NO");
                dt.Columns.Add("YN");

                dt.Rows.Add(1, "Y");
                dt.Rows.Add(1, "N");

                Dictionary<object, string> lst = new Dictionary<object, string>();

                lst["Y"] = "Y";
                lst["N"] = "N";
                lst["K"] = "K";

                Fx.DataContext = dt;
                Fx.AutoGenerateColumns = false;

                   Column c = new Column();
                c.Binding = new Binding("NO");

                Column c1 = new Column();
                c1.Binding = new Binding("YN");

                Fx.Columns.Add(c);
                Fx.Columns.Add(c1);

                Fx.Columns[1].ValueConverter = new UsedColumnValueConverter(lst);

// Fx.Rows.Add <== 하면 데이타 안늘어남. 참 뭐같음.
// 고로 원본을 꺼내 직접 Add 시켜야 함. 


                for (int i = 201001; i < 201012; i++)
                {
                    DataRow dr = dt.NewRow();
                    foreach (Column c in dt.Columns)
                    {
                        dr[c.ColumnName] = 0;
                    }
                    dr[0] = i;

                    dt.Rows.Add(dr);
                }
             
              //  Fx.Rows.Add(new Row());    // Row증가가 되지 않음.



.xaml

<c1Flex:C1FlexGrid  Grid.Row="1" Grid.Column="2" Name="Fx"  ItemsSource="{Binding}"  >
c1Flex:C1FlexGrid>



여기서 필요한건 새로 만든 UsedColumnValueConverter

 public class UsedColumnValueConverter : IValueConverter, IEditValueConverter
   
{
        IDictionary<object, string> dic = null;
        bool Ex = true;

        public UsedColumnValueConverter(IDictionary<object, string> idic)
        {
            dic = idic;
        }

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (dic.Keys.Contains(value))
                return dic[value];
            else
                return value;
             //
return null;     //널값 주면 값이 사라져버림.

        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;

           // return DependencyProperty.UnsetValue;
        }

        public bool Exclusive
        {
            get { return Ex; }
        }

        public ICollection Values
        {
            get {
              return  dic.Values.ToList();
           
            }
        }
    }



PS : 컨트롤에 대한 스터디 시간이 없으므로 다른 컨트롤로 교체됨.

'# 3) .Net ( Vs 2008 ) > WPF' 카테고리의 다른 글

WPF Textbox의 Numeric!  (0) 2015.09.05
WPF 에서 Keyboard 입력 하기 Winfom SendKeys 같은..  (0) 2011.09.08
IValueConverter 사용 데모  (0) 2010.09.06
WPF 쓰레드 ( 프로그래스바 )  (0) 2010.08.10
[WPF] Tab 순환코드  (0) 2010.07.27


 오늘 만든 폼에 사용해야 될 객체중 하나로 사용해본 후 기록함.

    // 정의
    public interface IValueConverter
    {
             object Convert(object value, Type targetType, object parameter, CultureInfo culture);
             object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
    }

 xaml에서 표현하는 컨트롤이 checkbox이고  내부 데이타(DB코드값)는 숫자타입 0 : false, 0 이 아니면 true라고 한다면...

[ValueConversion( typeof(int), typeof(bool))]
 public class IntToBoolenValueConverter : IValueConverter
    {
        #region IValueConverter 멤버
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int i = System.Convert.ToInt32(value);
            return i != 0;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool b = System.Convert.ToBoolean(value);
            return b ? 1 : 0;
        }
        #endregion
    }

위와 같이 구현한다.

추가:  ValueConversion 속성순서처럼
int -> bool은 convert메서드에서
bool -> int는 ConvertBack 메서드에서 각각 구현순서로 기억하면 편하다
.




< 아래 소스 실행화면 >


/********************************************************************************************************
.xaml 내용
<Window x:Class="IValueConverterDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Me="clr-namespace:IValueConverterDemo"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
    
        <ResourceDictionary>             
            <Me:IntToBoolenValueConverter x:Key="intToBoolenValueConverter" ></Me:IntToBoolenValueConverter>
            <DataTemplate x:Key="ListBoxItemTemplate" >
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="{Binding Path=dtChecked, Converter={StaticResource intToBoolenValueConverter}}"></CheckBox>
                    <TextBlock Text="{Binding Path=dtText}"></TextBlock>                   
                </StackPanel>
            </DataTemplate>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <ListBox Name="LstBox" ItemsSource="{Binding}" ItemTemplate="{StaticResource ListBoxItemTemplate}" ></ListBox>
    </Grid>
</Window>

.cs 내용

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;

namespace IValueConverterDemo
{
    /// <summary>
    /// Window1.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            DataTable dt = new DataTable();
            dt.Columns.Add("dtChecked");
            dt.Columns.Add("dtText");

            dt.Rows.Add( 1, "0 to False , 1 to True");
          dt.Rows.Add( 0, "0 to False , 1 to True");

            LstBox.DataContext = dt;
        }
    }

    [ValueConversion( typeof(int), typeof(bool))]
    public class IntToBoolenValueConverter : IValueConverter
    {
        #region IValueConverter 멤버
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int i = System.Convert.ToInt32(value);
            return i != 0;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool b = System.Convert.ToBoolean(value);
            return b ? 1 : 0;
        }
        #endregion
    }

}




 WPF 에 프로그래스 바를 사용할때!! 무거워서일까낭..?? 프로그래스에 진행도가 제대로 표현되지 않아서
쓰레드를 보았다.

아래 소스는 두가지를 주안점으로 했다.

첫번째 대리자 비동기 호출은 데브피아에서 비동기 구현관련해서 강좌를 보고 ...
           ( 전에 공부했던 내용이었는데 기억이 안나는건... )

두번째 Thread내에서의 Invoke를 이용해 대리자로써 메서드를 위임하는 부분이 WPF에서는 어찌 되는가를 알아보았다.

# 막상 Invoke를 써보니 Winform과 크게 다른건 없다. Dispatcher라는 프로퍼티에 Invoke를 이용할뿐이다.

 TextBox, Button, ProgressBar   이렇게 구성되어 있다.

   /// <summary>
    /// Window1.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        public delegate void delegateSetTextRender(object i, int cnt);
        public void SetTextRender(object i, int cnt)
        {
            textBox1.AppendText(i.ToString() + "\r\n");
            progressBar1.Value = cnt;
        }

        public void INProgressValue(int Progress)
        {
            progressBar1.Value = Progress;
        }
        public void INProgressMaxValue(int Progress)
        {
            progressBar1.Maximum = Progress;
        }
        public void INProgressMinValue(int Progress)
        {
            progressBar1.Minimum = Progress;
        }


        public delegate void delegateProgress(int i);

        const int SEARCHCOUNT = 20000;

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            // 기본쓰레드로 할때 
            //Thread th = new Thread(new ThreadStart( DoEvent ));
            //th.Start();

            // 비동기로 구현할 때.
               Action ac = new Action(DoEvent);
            AsyncCallback  async = new AsyncCallback(_EndInvoke);
            IAsyncResult ir =  ac.BeginInvoke(async, ac);

        }

        void _EndInvoke( IAsyncResult iar )
        {
           Action ac = iar.AsyncState as Action;
           while (iar.IsCompleted == false)
           {
               Thread.Sleep(100);
           }
           ac.EndInvoke(iar);
       
        }

        /// <summary>
        /// ///////////////////////////////////////////////////
        /// </summary>
        void DoEvent()
        {
            this.Dispatcher.Invoke(new delegateProgress(INProgressValue), new object[] { 0 });
            this.Dispatcher.Invoke(new delegateProgress(INProgressMaxValue),
                                                                                       new object[] { SEARCHCOUNT });
            this.Dispatcher.Invoke(new delegateProgress(INProgressMinValue), new object[] { 0 });


            List<int> sosuList = new List<int>();
            sosuList.Add(2);

            // 검사대상수 1과 2는 건너뜀...
            int number = 3;
        

            // 소수 3만개 찾기위한 루프
            while (sosuList.Count <= SEARCHCOUNT)
            {
                // 소수 검사 결과 일단은 소수라고 의심
                bool result = true;

                // 소수 검사
                double stopNumber = Math.Sqrt(number);
                foreach (int i in sosuList)
                {
                    if ((number % i) == 0)
                    {
                        result = false;
                        break;
                    }
                    if (i > stopNumber) break;
                }
              
                // 진짜 소수면 리스트에 저장
                if (result)
                {
                    this.Dispatcher.Invoke(new delegateProgress(INProgressValue),
                                                                                   new object[] { sosuList.Count });
                    sosuList.Add(number);
                }

                // 검사대상 수 증가
                number++;

                // 검사수에 제한을 둠
                if (number > 20000000) break;
            }

           // this.Dispatcher.Invoke(new delegateProgress(INProgressValue),new object[] { 0 });
            // 추가적으로 파라미터 Thread !!를 구현하는 방법이다.
            Thread th = new Thread(new ParameterizedThreadStart(Dispaly));
          th.Start(sosuList);
                    
        }

        void Dispaly(object prms)
        {
            IList<int> sosuList = prms as IList<int>;
            int cnt = sosuList.Count;
            foreach (int val in sosuList)
            {
                 this.Dispatcher.Invoke(new delegateSetTextRender(SetTextRender),
                                                                                           new object[] { val, --cnt });
               // this.textBox1.AppendText(val.ToString() + "\r\n");
            }
        }
    }

'# 3) .Net ( Vs 2008 ) > WPF' 카테고리의 다른 글

FlexGrid : WPF 콤보 컬럼 (Combo Column Type)  (0) 2010.09.07
IValueConverter 사용 데모  (0) 2010.09.06
[WPF] Tab 순환코드  (0) 2010.07.27
툴을 제작 해서 프로젝트를... 진행하다!  (0) 2010.02.26
WPF 3D  (0) 2009.12.29


 KeyboardNavigation.TabNavigation="Cycle"

페이지 내의 포커스가 마지막엘리먼트 이후 외부로 또는 어딘지 모르는곳으로 튀는것을 막기위해
처음엔 FocusManager.FocusedElement="{Binding ElementName=포커스지정엘리먼트명}"
으로 작성하여 잘 되는것처럼 보였으나...

탭컨트롤 안으로 들어가서 계층구조의 깊이가 깊어질수록 난해하고 복잡함에 지정된대로 적용도 안되고 하여
MSDN을 다시 읽어보던 중 키보드네비게이션을 발견!!

아쒸~~ 꼬박 하루 삽질해서 찾은거네.. ㅋㅋ  어쨌든..
참조 : http://msdn.microsoft.com/ko-kr/library/aa969768(VS.90).aspx#Keyboard_Focus 

열심히 바꿔야겠군...

2015-09-05

     첨부파일을 추가했음 ( 내부 ) : 사용자정의용컨트롤에 대한 처리.

'# 3) .Net ( Vs 2008 ) > WPF' 카테고리의 다른 글

IValueConverter 사용 데모  (0) 2010.09.06
WPF 쓰레드 ( 프로그래스바 )  (0) 2010.08.10
툴을 제작 해서 프로젝트를... 진행하다!  (0) 2010.02.26
WPF 3D  (0) 2009.12.29
데이타바인딩(2)  (0) 2009.12.28


VB.NET을 계속 수정하다 보니 지루하고 짜증만 나고 익숙하지 않은 노트북 키보드에... 여러가지 힘든점을

늘 그렇듯... 이번에도 툴을 만들었다.

훨씬 객체간에 데이타 주고 받는 느낌은 심플하다..

그리드 컬럼으로 부터 -> 출발해서...

완성되는 소스에 조각 조각 코드를 생성해서 붙여넣는다..


          >> 우측 하단에 뜨는 메인폼임. ( 트레이 가능 )


>> 왼쪽 코드를 붙여넣으면 정규식에 의해 변수만 체크해서 리스트화 한다.


>> 리스트화된 변수에 대한 셋팅을 한다. 이는 그리드 셋팅 문구를 만들어내는데 필요한 설정내역이다.


 >> 만들어낸 결과물이다... 이를 복사해서 붙여넣으면 된다.



>> 그리드의 컬러 셋팅구문을 만들내는 화면이다. 그리드 컬럼을 선택하고 만들어내서 붙여넣기 하면 된다.


>> 그리드내에서 코드들을 찾는 폼을 띠울때 설정하는 몇가지 이벤트 코드를 한꺼번에 뽑아낼수 있는 화면이다.
 일일이 치는게 만만한 일이 아니어서...


>> 폼 상단에 추가되는 버튼들의 이벤트와 생성을 뽑아내는 화면이다.. 등록하고 뽑아내면 쉽게 만들어낸다.


>> J 라는 빨간 아이콘은 해당 프로그램이 트레이에 들어가있을때의 아이콘임... ( 캬~~ )





이로써 일주일간 테스트 해본결과... 작업이 굉장히 빠른데... 겁나게 피곤하다..

그래도.. 일일이 타이핑하기에 너무 많은 양이라... 이렇게 하지 않음... 못버티겠다...

또 하나의 툴을 만들어내고 업글하는 재미로.. 지금 프로젝트는 진행 되고 있다.

'# 3) .Net ( Vs 2008 ) > WPF' 카테고리의 다른 글

WPF 쓰레드 ( 프로그래스바 )  (0) 2010.08.10
[WPF] Tab 순환코드  (0) 2010.07.27
WPF 3D  (0) 2009.12.29
데이타바인딩(2)  (0) 2009.12.28
데이타바인딩(1)  (0) 2009.12.28

WPF 3D

# 3) .Net ( Vs 2008 )/WPF2009. 12. 29. 01:09
 프로그래밍을 하면서 3D.. 언젠가 해보고 싶었다!

.Net 2.0을 할때도 다이렉트X 지원없이 순수 수학적개념을 바탕으로 구현해보고자 해서 별짓 다해봤다.
행렬계산도 마다않고 API를 만들었던 기억이 난다.
 끝내 완성은 못했지만 ㅠㅠ;..  소스를 얻었다 어디선가 3D를 구현해둔게 있었다..

 다이렉트X에서 말하는 파이프라인을 직접 GDI+ 를 이용한 소스를 손에 넣고 돌려보고 감탄하고
접어버렸다.

 다시 접하게 된 WPF 3D...
우선 책에 있는 소스 그대로 쳐봤다. 멋지군...

사용자 삽입 이미지

해보려고 했더니 그닥...특별한게 없넹...

<ViewPort3D>요소 안에 3D를 구현하게 되는데

필요한 요소에 대한 설명이 있음.
 1. GeometryModel3D 형식에 객체,
 2. 빛과 관련된 광원객체
 3. 카메라 그리고 관찰자

참 말은 다르지만 낯익은 단어들...

- 3D구성요소
 Models    
 Meterials
 Camera
 Light

매쉬( Mesh ) : 3D 객체는 삼각형의 조합을 통해 구성된다. 이렇게 삼각형 조합을 통해 구성된 3D모델
WPF에서는 이러한 모델을 구성하기 위해 GeometryModel3D와 MeshGeometry3D를 이용함.

음... 그닥 책에서 건질건 없네...

췌~

'# 3) .Net ( Vs 2008 ) > WPF' 카테고리의 다른 글

[WPF] Tab 순환코드  (0) 2010.07.27
툴을 제작 해서 프로젝트를... 진행하다!  (0) 2010.02.26
데이타바인딩(2)  (0) 2009.12.28
데이타바인딩(1)  (0) 2009.12.28
이벤트 종류 & 명령 & 트리거  (0) 2009.12.28