퇴근5분전

http://book.daum.net/detail/book.do?bookid=KOR9788979145267

 객체지향 공부할때 보던책인데...
 만약 후임이 공부를 한다면 가장 추천해주고 싶은데...

나름 스토리를 가지고 신입이 들어와서 어떤 문제해결을 위해 패턴을 적용하는 과정들을 소재로 풀어가는
재미난 책임.

중후반부는 아직도 모르겠음. ( 내공부족 )

'--- 취미 > 읽은 책관련' 카테고리의 다른 글

.NET 3.5 차세대 개발 프로그래밍  (0) 2009.12.31
2막  (0) 2009.12.31
누워서 읽는 알고리즘  (0) 2009.12.31
성공과 실패를 결정하는 1%의 객체지향 원리  (0) 2009.12.31
좋은 프로그래밍 습관  (0) 2009.12.31

http://book.daum.net/detail/book.do?bookid=KOR9788931548563

객체 지향 관련해서 고심할때 보던책임.

'--- 취미 > 읽은 책관련' 카테고리의 다른 글

.NET 3.5 차세대 개발 프로그래밍  (0) 2009.12.31
2막  (0) 2009.12.31
누워서 읽는 알고리즘  (0) 2009.12.31
패턴 그리고 객체지향적 코딩의 법칙  (0) 2009.12.31
좋은 프로그래밍 습관  (0) 2009.12.31

http://book.daum.net/detail/book.do?bookid=KOR9788975603105

좋은 프로그래밍 습관이란 책으로 프로그래밍상에서 주의 할것이라든가 이런 저런 내용들을 담은 책인데
61가지... 나름 재미있게 보았고.

 프로그래밍을 처음 하던 초기에 고심하던 내용들이 나름 많이 담겨있어서 도움이 되었던...

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

데이타템플릿
 ListBox에 ToString() 말고, 임의의 모습으로 나타내고자 할때 사용할수 있음.

사용자 삽입 이미지
<DataTemplate으로 적용된 화면>


Window.xaml
<Window x:Class="OneTimeDataBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"       
    xmlns:myClass="clr-namespace:OneTimeDataBinding"
    Title="Window1" Height="236" Width="300" Loaded="Window_Loaded">
    <Window.Resources>
        <myClass:Code x:Key="cd" Name="_ResourceName" ></myClass:Code>

        <DataTemplate x:Key="dt" DataType="{x:Type myClass:Code}">
          <StackPanel Orientation="Horizontal">
             <TextBlock Text="{Binding Path=Name}" Foreground="Blue"></TextBlock>
             <TextBlock Text=":"></TextBlock>
             <TextBlock Text="{Binding Path=Age}" Foreground="Chartreuse"></TextBlock>               
            </StackPanel>
               
        </DataTemplate>    

    </Window.Resources>
    <Grid Height="289" x:Name="Grid1" DataContext="{StaticResource cd}">
        <Grid.RowDefinitions>
            <RowDefinition Height="65*" />
            <RowDefinition Height="224*" />
        </Grid.RowDefinitions>
        <TextBox Margin="12,12,73,10" Name="textBox1" Text="{Binding Path=Name}" />
        <Button HorizontalAlignment="Right" Margin="0,12,12,10" Name="button1" Width="55" Click="button1_Click">Button</Button>
        <Grid Name="Grid2" Margin="0,12,0,100" Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="132*" />
                <ColumnDefinition Width="146*" />               
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="89.473*" />
                <RowDefinition Height="23.527*" />
            </Grid.RowDefinitions>
            <TextBlock Text="{Binding Path=Name}" Margin="12,0,12,6" Grid.Row="1" Height="17.527" VerticalAlignment="Bottom"></TextBlock>
            <TextBlock Text="{Binding Path=Age}" Margin="12,0,26,10" Grid.Row="1" Grid.Column="1" Height="13.527" VerticalAlignment="Bottom"></TextBlock>
            <ListBox Margin="12,6,0,6" Name="listBox1" ItemsSource="{Binding}" Grid.ColumnSpan="2"
                 HorizontalAlignment="Left" Width="260" SelectionChanged="listBox1_SelectionChanged"
                  ItemTemplate="{StaticResource dt}" />
        </Grid>
    </Grid>
</Window>

Window.xaml.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.ComponentModel;

namespace OneTimeDataBinding
{
    /// <summary>
    /// Window1.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class Window1 : Window
    {
        Code cd = new Code();

        public Window1()
        {
            InitializeComponent();
            cd.Name = "초기 코드값";
            Grid1.DataContext = cd;
        }
      

        private void button1_Click(object sender, RoutedEventArgs e)
        {
           cd.Name = "변경 값";          
           //MessageBox.Show(cd.Name);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            CodeList cd = new CodeList();
            cd.Add(new Code() { Name = "Code1", Age=1});
            cd.Add(new Code() { Name = "Code2", Age=2 });
            cd.Add(new Code() { Name = "Code3", Age=3 });

            listBox1.DataContext = cd;
        }

        private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Grid2.DataContext = e.AddedItems; 
        }
    }

    ///// <summary>
    ///// 단일 바인딩 모델에서 사용한 클래스.
    ///// </summary>
    //public class Code
    //{
    //    string name = string.Empty;
    //    public string Name { get; set; }
    //}

    /// <summary>
    /// 코드 리스트
    /// </summary>
    public class CodeList : List<Code>
    {

    }


    /// <summary>
    ///
    /// 단방향 모델에서 사용한 클래스.
    /// </summary>
    public class Code : INotifyPropertyChanged
    {
        string name = string.Empty;

        public string Name { get { return name; } set { name = value; Update("Name"); } }

        int age = 0;

        public int Age { get { return age; } set { age = value; Update("Age"); } }


        #region INotifyPropertyChanged 멤버

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public void Update(string PropertyName)
        {
            if( PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }

        public override string ToString()
        {
            return name;
        }
    }

}

특정 객체에 저장된 데이타가 출력되는 화면을 정의하여 템플릿화 할수 있는데
이를 데이타 템플릿이라 한다.

ObservableCollection<T> : 책에 오타 있으므로 철자 주의!

위 소스에서 이전, 다음 버튼을 추가후 각각 버튼 처리를 한다.

// 이전
       private void button2_Click(object sender, RoutedEventArgs e)
        {
            ICollectionView view = CollectionViewSource.GetDefaultView(listBox1.DataContext);
            view.MoveCurrentToPrevious();
            if (view.IsCurrentBeforeFirst)  view.MoveCurrentToFirst();
            //Grid2.DataContext = view.CurrentItem as Code;
            listBox1.SelectedItem = view.CurrentItem;
        }
//다음
        private void button3_Click(object sender, RoutedEventArgs e)
        {
            ICollectionView view = CollectionViewSource.GetDefaultView(listBox1.DataContext);
            view.MoveCurrentToNext();
            if (view.IsCurrentAfterLast)  view.MoveCurrentToLast();
            //Grid2.DataContext = view.CurrentItem as Code;
            listBox1.SelectedItem = view.CurrentItem;
        }

이때 새로운 데이타 추가시~~ CodeList 가 변경 되는데 이때 컨트롤에 적용시키는 기능이 포함되어 있지 않다.

INotifyPropertyChanged 인터페이스가 List<T>에는 적용되어 있지 않아 갱신되지 않으므로
WPF에서는 이를 적용한 ObservableCollection<T> 제너릭컬렉션에 데이타를 저장하면 자동으로 갱신된다.

테스트 해보니 일반 List<T>를 사용하여 추가기능을 구현했을때는
추가후 ListBox에 추가된 Item은 보이지 않았음.

ObservableCollection<T>를 사용하여 구현하니 추가시 바로 갱신되는것을 확인하였음.

    public class oCodeList : ObservableCollection<Code>
    {    
    }

public class Window1 : Window
{
       ...

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            oCodeList cd = new oCodeList();
            // CodeList cd = new CodeList();           
            cd.Add(new Code() { Name = "Code1", Age=1});
            cd.Add(new Code() { Name = "Code2", Age=2 });
            cd.Add(new Code() { Name = "Code3", Age=3 });

            listBox1.DataContext = cd;
        }

       /// 추가 기능
       private void button4_Click(object sender, RoutedEventArgs e)
        {
            oCodeList ls = listBox1.DataContext as oCodeList;
            //CodeList ls = listBox1.DataContext as CodeList;
            if (ls != null)
                ls.Add(new Code() { Name="add1", Age=ls.Count+1 });
        }
}

컨트롤 데이타 바인딩
 임의의 WPF 컨트롤에 설정된 데이타를 다른 컨트롤에 바인딩 할수도 있다.
이때 속성대 속성의 매칭을 통해 데이타의 이동이 발생한다.

간단히 바인딩 표현식이 바뀐다

<바인딩컨트롤
      Background="{Binding ElementName=대상컨트롤이름, Path=대상컨트롤속성이름}" ...
 />

책페이지 321부터 간략히 설명되있음...


me : 바인딩에 대해 2회로 나누어 확인하였음.
DataTemplate를 가지고 표시되는 형태를 마음대로 바꿀수 있다는 점이 역시 흥미로웠음.
다른부분은 .Net 2.0에서 코딩량이 좀 되지만 나름 구현이 가능했던 것들이라...
WPF에서의 바인딩 구현방법이 좀더 편하다는 생각이 들기도 했지만... 데이타 타입별로 Class화 해야된다면 파일또한 많아 지겠구나 싶었음. 필요하다면 지금까지 해왔던 방법대로 DataTable을 바인딩 걸어서 써보고 싶음.




- 출처 : .Net 3.5 차세대 개발 프로그래밍 -  책에서 일부 정리 함. ( 저작권 문제시 삭제 할 것임. )
          자세한 내용은 책을 통해 확인하시길...

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

툴을 제작 해서 프로젝트를... 진행하다!  (0) 2010.02.26
WPF 3D  (0) 2009.12.29
데이타바인딩(1)  (0) 2009.12.28
이벤트 종류 & 명령 & 트리거  (0) 2009.12.28
컨트롤  (0) 2009.12.28

데이타 바인딩 모델
  1. 단일         : 읽기전용 바인딩 모델
  2. 단방향      : 읽기전용 바인딩 모델 & 저장소데이타 변경시 자동 변경
  3. 양방향      : 읽기/쓰기 바인딩 모델

- 단일
  데이타를 값 대입해주는 형태로 사용함.( 기존 Form작업시 많이 사용했음. )
 컨트롤.프로퍼티 = 저장소.프로퍼티;

- 단방향
  객체의 상태변화를 이용해서 변경시 자동으로 바인딩된 컨트롤에 반영되도록 해주는 모델
  -- 객체 상태 변화
   객체의 상태변화시 System.ComponentModel.INotifyPropertyChanged 를 이용하여 제어가 가능하다.
 
    /// <summary>
    /// 단방향 모델에서 사용한 클래스.
    /// </summary>
    public class Code : INotifyPropertyChanged
    {
        string name = string.Empty;
        public string Name { get { return name; } set { name = value; Update("Name"); } }

        #region INotifyPropertyChanged 멤버
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
        public void Update(string PropertyName)
        {
            if( PropertyChanged != null)
              PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
 
   이렇게 인터페이스를 구현하고 윈도우폼 상에서 이벤트를 정의 하여 객체 변화 시
  데이타를 갱신해주는 형태로 구현이 된다.

책에는 양방향 언급이 초반에 살짝 있고 사라졌다...
대신 바인딘 표현식 이란것으로 대체 한듯한데...

바인딩 표현식
           Code cd = new Code();
           cd.Name = "초기 코드값";
           textBox1.DataContext = cd;  // 데이타 원본 할당
데이타를 컨트롤에 바인딩 하고
<TextBox  Name="textBox1" VerticalAlignment="Top" Text="{Binding Path=Name}" />
컨트롤 프로퍼티에 바인딩되는 데이타객체의 프로퍼티를 지정하여 결정한다.



바인딩 방향에 대한 문제는 저장소 객체 -> 데이타표출컨트롤 쪽에 해당하는 문제인듯 함.
이유:
 테스트 해본결과
    1. 저장소객체와 컨트롤을 바인딩 : <... Text="{Binding Path=Name}" />
    2. 저장소객체의 프로퍼티를 이용한 데이타 변경 :  데이타 표출컨트롤 반영 안됨.
    3. 데이타표출컨트롤에서 값 변경 : 저장소객체 데이타변경되있음.

private void UpdateBtn_Click(object sender, RoutedEventArgs e)
{
      cd.Name = "변경 값";                  
}

일때

    /// <summary>
    /// 단방향 모델에서 사용한 클래스.
    /// </summary>
    public class Code : INotifyPropertyChanged
    {
        string name = string.Empty;

        public string Name { get { return name; } set { name = value; Update("Name"); } }

        #region INotifyPropertyChanged 멤버

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public void Update(string PropertyName)
        {
            if( PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));       // -----①
        }
    }

따로 Code객체에 PropertyChanged 에 이벤트핸들러를 추가하지 않고 있으나

① 이 주석여부에 따라~!!!  표출컨트롤에 데이타 갱신이 일어나는것으로 보아
 바인딩 될때 내부적으로 PropertyChanged 이벤트에 핸들러를 추가하는듯 함.

의존 속성 ( Dependency Property )
 
Window.xaml
 <Grid Height="48" x:Name="Grid1">
        <TextBox Height="23" Margin="12,12,73,0" Name="textBox1" VerticalAlignment="Top" Text="{Binding Path=Name}" />
        <Button Height="23" HorizontalAlignment="Right" Margin="0,12,12,0" Name="button1" VerticalAlignment="Top" Width="55" Click="button1_Click">Button</Button>
    </Grid>

Window.xaml.cs
        Code cd = new Code();
        public Window1()
        {
            InitializeComponent();
            cd.Name = "초기 코드값";
            Grid1.DataContext = cd;
        }
 
위와 같이 TexBox에 바인딩 표현식이 존재하나 실제 바인딩 원본은 Grid1.DataContext 에 바인딩 되어있을시  그리드에 하위 요소인 TextBox에서는 자신에게 바인딩된 원본이 없으므로 상위 객체에서 바인딩원본을 찾게 된다. 이때 Text 가 곧 의존 속성이 된다. ( 이해한대로 썼음... )


선언적 데이타 원본

<Window.Resources>
   <Code x:Key="cd" xmlns="clr-namespace:OneTimeDataBinding" Name="_ResourceName" ></Code>
</Window.Resources>
   <Grid Height="48" x:Name="Grid1" DataContext="{StaticResource cd}">
        <TextBox Height="23" Margin="12,12,73,0" Name="textBox1" VerticalAlignment="Top" Text="{Binding Path=Name}" />
        <Button Height="23" HorizontalAlignment="Right" Margin="0,12,12,0" Name="button1" VerticalAlignment="Top" Width="55" Click="button1_Click">Button</Button>
    </Grid>

이런식으로 되있다.

<Code> 는 컴파일시 Code 객체로 변환되고 그리드에 바인딩하고 TextBox는 의존속성에 의해 그리드에 원본데이타를 표시하게 됨.

선언적이란건 리소스에 데이타원본을 선언한다라는 의미인듯 하다.


다중 데이타 바인딩
 리스트 박스 같은 여러개의 객체를 바인딩 할때...

List를 이용하고 ToString을 재정의 하고, 의존속성을 이용하고 하니 간편하게 코딩이 가능하다눈...

책에 300페이지 ~ 307페이지 내용인데.

Window.xaml.cs
 private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            CodeList cd = new CodeList();
            cd.Add(new Code() { Name = "Code1", Age=1});
            cd.Add(new Code() { Name = "Code2", Age=2 });
            cd.Add(new Code() { Name = "Code3", Age=3 });

            listBox1.DataContext = cd;
        }

        private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Grid2.DataContext = e.AddedItems; 
        }

Window.xaml
 <Grid Name="Grid2" Margin="0,12,0,100" Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="132*" />
                <ColumnDefinition Width="146*" />               
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="89.473*" />
                <RowDefinition Height="23.527*" />
            </Grid.RowDefinitions>
            <TextBlock Text="{Binding Path=Name}" Margin="12,0,12,6" Grid.Row="1" Height="17.527" VerticalAlignment="Bottom"></TextBlock>
            <TextBlock Text="{Binding Path=Age}" Margin="12,0,26,10" Grid.Row="1" Grid.Column="1" Height="13.527" VerticalAlignment="Bottom"></TextBlock>
            <ListBox Margin="12,6,0,6" Name="listBox1" ItemsSource="{Binding}" Grid.ColumnSpan="2" HorizontalAlignment="Left" Width="260" SelectionChanged="listBox1_SelectionChanged" />
        </Grid>



꾀 길어졌는데 잘라볼까낭..

- 출처 : .Net 3.5 차세대 개발 프로그래밍 -  책에서 일부 정리 함. ( 저작권 문제시 삭제 할 것임. )
          자세한 내용은 책을 통해 확인하시길...

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

WPF 3D  (0) 2009.12.29
데이타바인딩(2)  (0) 2009.12.28
이벤트 종류 & 명령 & 트리거  (0) 2009.12.28
컨트롤  (0) 2009.12.28
스타일  (0) 2009.12.26

이벤트의 종류에는

 1. 직접 이벤트
 2. 이벤트 버블링
 3. 이벤트 터널링


- 직접 이벤트
  : 단일 컨트롤에 등록되는 이벤트 ( 기존 폼 같은... )

- 이벤트 터널링
  : 컨트롤의 비쥬얼 트리에서 이벤트를 발생시킨 컨트롤의 최상위 부모 컨트롤부터 관련 컨트롤까지 Preview 접두어가 명시된 이벤트가 차례로 처리되는 것

- 이벤트 버블링
 : 터널링이 끝난후 이벤트를 발생시킨 컨트롤로부터 부모컨트롤로 Preview 접두어가 명시되지 않은 이벤트가 차례로 발생 처리되는 것

모든 컨트롤에서 이벤트터널링과 이벤트 버블링이 발생하지 않는다.

명령( Command )
 : 특정 컨트롤에 종속적이지 않고 범용적으로 사용할수 있는 이벤트들이 있는데 ,
 잘라내기, 복사, 붙여넣기 등과 같은 이벤트가 대표적인 경우이다.

ICommand 인터페이스를 상속받은 클래스를 정의 한 후 이를 이용한다.

MyCommand.cs
namespace Evt_ICommand
{
    public class MyCommand : ICommand
    {
        #region ICommand 멤버

        public bool CanExecute(object parameter) // 명령을 실행가능한지.
        {
            return true;
        }

        public event EventHandler CanExecuteChanged; // 명령 값이 변화가 발생시...

        public void Execute(object parameter) // 명령처리
        {
            // 파라미터가 null값이 들어옴. ( Test중...)
            Application.Current.Shutdown();
        }

        #endregion
    }
}

Evt-Command.xaml.cs
        <Menu>
            <!-- 1번째 -->
            <MenuItem Header="종료">
                <MenuItem.Command>
                    <MyCommand xmlns="clr-namespace:Evt_ICommand"></MyCommand>
                </MenuItem.Command>
            </MenuItem>

            <!-- 2 번째 -->
            <MenuItem Command="ApplicationCommands.Paste" Header="붙여넣기">               
            </MenuItem>
        </Menu>
 
me: 이렇게 명령을 사용하니까... 명령별로 구분해서 만들고 이벤트대신 명령으로 컨트롤들에 공통 이벤트로 적용이 될만도 한데... 코딩이 좀더 들어갈듯... 좀더 고민해보면 응용이 필요한곳에 적절하게 사용할수 있을듯도 ...

책 Page 260 에 커맨드 종류가 나와있음. 이를 참고!!
  - ApplicationCommands
  - ComponentCommands
  - MediaCommands
  - NavigationCommands
  - EditingCommands

  2번째 명령을 적용해보니 다른 코딩없이 클립보드에서 데이타를 가져와서 붙여넣기가 되었음...


명령바인딩 
 해당 명령이 발생시 이 명령에 대한 별도의 작업을 처리하는 메서드를 호출가능하게 함.
window.xaml
<Window x:Class="Evt_ICommand.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">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Paste"
                        Executed="CommandBinding_Executed"
                        CanExecute="CommandBinding_CanExecute" >
        </CommandBinding>
    </Window.CommandBindings>
    <Grid>
        <Menu>
            <MenuItem Header="종료">
                <MenuItem.Command>
                    <MyCommand xmlns="clr-namespace:Evt_ICommand"></MyCommand>
                </MenuItem.Command>
            </MenuItem>
            <MenuItem Command="ApplicationCommands.Paste" Header="붙여넣기">               
            </MenuItem>
        </Menu>
        <TextBox Margin="0,21,0,0" Name="textBox1" TextWrapping="WrapWithOverflow"/>
    </Grid>
</Window>

window.xaml.cs
    /// <summary>
    /// Window1.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
//               명령에 대한 추가작업
                  MessageBox.Show("붙여넣기 실행!");          
        }
        private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
//             명령 사용여부
                e.CanExecute = true;
       
}
    }

음... 이게 좀 의문점이 있음.
커서가 TextBox안에 없을때 붙여넣기 메뉴 아이템을 클릭하면 메세지 박스가 실행되지만
TextBox에 커서가 위치된후 붙여넣기 메뉴 아이템 클릭시 메세지 박스가 실행이 안됨.
커서위치 해놓고 Ctrl+V를 눌러도 안됨.

트리거
 : 스타일에 조건을 명시해 적용시키는 데 사용한다.

    <Window.Resources>
        <Style TargetType="{x:Type MenuItem}">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Yellow"></Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

'메뉴아이템에 대한 스타일적용시 IsMouseOver 가 True이면 Background를 Yellow로 변경하여라'
라는 의미의 구문이 된다.

실제 적용해보면 마우스가 메뉴 아이템 위에 올라갔을시 바탕이 노란색으로 바뀌는 것을 볼수 있음.

WPF를 공부시 문법관련해서 외워서 칠 정도가 되려면 좀더 걸리겠다!!
처음 Asp.Net을 공부할때 HTML은 옛날 공부해둔덕에 그만한한 공부에 공들이는 시간을 줄일수 있었다지만.. 이건 뭐... 많긴 많다.


다중 트리거다중 조건 트리거는 책 267~269페이지 참조..

요약 : 다중트리거는 기존 트리거를 몇개 더 붙여놓는거였고...
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Yellow"></Setter>
                </Trigger>
             <Trigger Property="IsFocus" Value="True">
                    <Setter Property="Background" Value="Red"></Setter>
                </Trigger>
            </Style.Triggers>

다중 조건 트리거는 여러조건들이 맞아야 스타일을 적용하는 방법임.
 <MultiTriggers>
        <MultiTrigger.Conditions>
             <Condition Property="IsMouseOver" Value="True"/>
             <Condition Property="IsFocus" Value="True"/>
              ...
        </MultiTrigger.Conditions>
         <Setter  스타일 ... >   </Setter>
 </MultiTriggers>

이외에 이벤트 트리거라는것도 있다고 쓰여있음.





- 출처 : .Net 3.5 차세대 개발 프로그래밍 -  책에서 일부 정리 함. ( 저작권 문제시 삭제 할 것임. )
          자세한 내용은 책을 통해 확인하시길...

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

데이타바인딩(2)  (0) 2009.12.28
데이타바인딩(1)  (0) 2009.12.28
컨트롤  (0) 2009.12.28
스타일  (0) 2009.12.26
리소스  (0) 2009.12.26

 컨트롤은 책에 간단히 설명되있지만... 기존에 .Net 2.0을 공부하듯이 할것임...

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

데이타바인딩(1)  (0) 2009.12.28
이벤트 종류 & 명령 & 트리거  (0) 2009.12.28
스타일  (0) 2009.12.26
리소스  (0) 2009.12.26
레이아웃 컨트롤  (0) 2009.12.26

스타일
 윈도우에 포함되는 여러 컨트롤에 일괄 적용하거나 여러 프로젝트에서 스타일을 사용하기 위해서
리소스영역에 해당 내용을 기술하고 컨트롤함.

<UserControl x:Class="WpfApplication1.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <UserControl.Resources>       
        <Style x:Key="fontStyle">
            <Setter Property="Control.FontSize" Value="15"></Setter>
        </Style>
    </UserControl.Resources>
    <Grid>
        <!--주석은 이렇게.. -->
        <Button Margin="31,28,47,50" Name="button1" Click="button1_Click" Background="{StaticResource YellowBrush}">Button</Button>
        <Button Style="{StaticResource fontStyle}" Height="44" Margin="68,59,90,0" Name="button2" VerticalAlignment="Top" Click="button2_Click">Button</Button>
    </Grid>
</UserControl>

명시적 스타일 선언
<Style TargetType="{x:Type Button}">
     <Setter Property="Button.FontSize" Value="15"></Setter>
</Style>


버튼에 강제로 스타일을 적용한다.

스타일 상속
        <Style x:Key="fontColor">
            <Setter Property="Control.Background" Value="Yellow"></Setter>
        </Style>
        <Style x:Key="fontStyle" BaseOn="{StaticResource fontColor}">
            <Setter Property="Control.FontSize" Value="15"></Setter>
        </Style>


컨트롤 템플릿
 컨트롤의 외형이나 기타속성들을 템플릿으로 구성하여 적용하는 방법으로 사용함.

- 선언
<Window.Resources>
      <ControlTemplate x:Key="BtnTemplate" >
            <Rectangle Fill="Yellow" />
      </ControlTemplate>
</Window.Resources>

- 적용
<Button Template="{StaticResource BtnTemplate}" />

명시적으로 컨트롤 템플릿 선언하기

<Style TargetType="{x:Type Button}">
     <Setter Property="Template">
         <Setter.Value>
           
  <ControlTemplate>
                      <Rectangle Fill="Yellow" />
                 </ControlTemplate>
        </Setter.Value>
     </Setter>
</Style>



- 출처 : .Net 3.5 차세대 개발 프로그래밍 -  책에서 일부 정리 함. ( 저작권 문제시 삭제 할 것임. )
          자세한 내용은 책을 통해 확인하시길...










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

이벤트 종류 & 명령 & 트리거  (0) 2009.12.28
컨트롤  (0) 2009.12.28
리소스  (0) 2009.12.26
레이아웃 컨트롤  (0) 2009.12.26
유저컨트롤사용!  (0) 2009.12.26

- 리소스
동적 리소스, 정적리소스로 구분되며 이는 런타임시 리소스의 내용이 변하는지에 대한 차이임.
Key와 Data를 저장하는 컬렉션이다.



정적 리소스 선언
  <Window ... >
      <Window.Resources>
           <SolidColorBrush x:Key="YellowBrush" Color="Yellow" />
      </Window.Resources>

        <Button Background="{StaticResource YellowBrush}" />
 </Window>
<Window.Resources>는 <컨트롤.Resource> 지정이 가능함.
StaticResource 키워드를 이용해 Key에 대한 값을 리소스컬렉션에서 찾아 적용한다.
{} 는 "" 안에 값을 값으로 인식하지 말고 해석하라는 의미임.

동적 리소스 선언
window.xaml
  <Window ... >
        <Button Background="{DynamicResource Window.Background}" Click="button1_Click" />
 </Window>

window.xaml.cs
  private void button1_Click(object sender, RoutedEventArgs e)
  {
        this.Background = Brushes.AliceBlue;                
  }
동적으로 리소스가 변경됨을 볼수 있음.


리소스만을 임의의 파일로 관리하는 방법
새항목 추가 시 : 리소스사전 항목 선택 후 생성

Dictionary1.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="YellowBrush" Color="Yellow" />
       ...사용할 리소스 등록...

</ResourceDictionary>

UserControl.xaml
<UserControl x:Class="WpfApplication1.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <UserControl.Resources>
        <ResourceDictionary Source="Dictionary1.xaml" ></ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <Button Margin="31,28,47,50" Name="button1" Click="button1_Click" Background="{StaticResource YellowBrush}">Button</Button>
        <Button Height="44" Margin="68,59,90,0" Name="button2" VerticalAlignment="Top" Click="button2_Click">Button</Button>
    </Grid>
</UserControl>


리소스 범위
 xml기반의 마크업으로 부모요소안에 자식요소들은 부모요소가 지니는 특징을 모두 갖게 된다.
리소스를 찾을때는 자식부터 상위계층으로 필요한 리소스요소가 있는지 찾아가게 됨.
 파일로 관리시 특정 리소스에 종속적으로 선언된것이 아니므로 모든 컨트롤에서는 리소스 사전에 등록된 리소스를 찾아 적용가능함.


프로그래밍상으로 리소스를 등록 & 찾는 방법
등록
  Resource.Add("YellowBrush" , Brushes.Yellow );
  Resource["YellowBrush"] = Brushes.Yellow;
검색
  적용컨트롤.Background = (Brush)컨트롤.FindResource("YellowBrush" );


어셈블리로 리소스관리하기
   이건 책에 p191 에 자세히 나와있으니 책 참조!



- 출처 : .Net 3.5 차세대 개발 프로그래밍 -  책에서 일부 정리 함. ( 저작권 문제시 삭제 할 것임. )
          자세한 내용은 책을 통해 확인하시길...




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

컨트롤  (0) 2009.12.28
스타일  (0) 2009.12.26
레이아웃 컨트롤  (0) 2009.12.26
유저컨트롤사용!  (0) 2009.12.26
WPF 응용프로그램 기초  (0) 2009.12.26