[WPF] Resource WPF 2012. 3. 14. 17:42

리소스는 런타임 당시 이용되어 쓰이는 데이터를 말하는 것이다. 아래는 리소스를 이용하여 컨트롤 변경 하는 예제이다.

앞서 포스팅 한 글에도 Window.Resource 를 정의하여 이용 했는데 그곳에 정의 된 내용을 쓰는 것과 동일한 내용이다.

<Window.Resources>
        <Style x:Key="LabelStyle1" TargetType="{x:Type Label}">
            <Setter Property="Foreground" Value="#FFFF0000"/>
            <Setter Property="Background" Value="#00FF0000"/>
            <Setter Property="Padding" Value="5"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Label}">
                        <Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="FontWeight" Value="Bold"/>
        </Style>
        <Style x:Key="LabelStyle2" TargetType="{x:Type Label}">
            <Setter Property="Foreground" Value="#FF002CFF"/>
            <Setter Property="Background" Value="#00FF0000"/>
            <Setter Property="Padding" Value="5"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Label}">
                        <Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="FontWeight" Value="Normal"/>
            <Setter Property="FontStyle" Value="Italic"/>
            <Setter Property="FontFamily" Value="Gulim"/>
            <Setter Property="FontSize" Value="20"/>
        </Style>

    </Window.Resources>

위와 같이 리소스를 정의 하고,

<Label Height="28" Margin="14,33,12,0" Name="label1" VerticalAlignment="Top" Padding="0"
               Style="{DynamicResource null}">Test</Label>
        <Button Height="23" HorizontalAlignment="Left" Margin="14,0,0,46" Name="btn1" VerticalAlignment="Bottom"  Width="75" Click="btn1_Click">Button Test</Button>
        <Button Height="23" Margin="105,0,98,46" Name="btn2" VerticalAlignment="Bottom"  Width="75" Click="btn2_Click">Resource1</Button>
        <Button Height="23" HorizontalAlignment="Right" Margin="0,0,12,46" Name="btn3" VerticalAlignment="Bottom"  Width="75" Click="btn3_Click">Resource2</Button>

와 같이 컨트롤을 올린 후 이벤트에 style을 FindResource를 이용하여 적용 시키면 된다. 명시적으로 캐스팅 해 주는 것을 잊지 말자.

[WPF] Control Template WPF 2012. 3. 14. 17:13
컨트롤 템플릿은 다양한 UI 형태로 만들기 위한 경우 이용이 됩니다.

다음은 버튼을 이용한 예제 입니다.

<Button Height="30" HorizontalAlignment="Center" Name="Btn" VerticalAlignment="Center" Width="100" Click="Btn_Click">
            <Button.Template>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <Ellipse Fill="Blue" Stroke="Yellow"/>
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                    </Grid>
                </ControlTemplate>
            </Button.Template>
        </Button>
[WPF] Data Template WPF 2012. 3. 14. 17:06

데이터 템플릿은 객체가 렌더링 될 시 적용가능한 UI의 한 부분으로 DataTemplate타입의 속성(Property)를  가지고 있다.

다음은 그 예제 이다. 먼저 cs 파일을 보자

using System.Collections.ObjectModel;

namespace WpfApplication5
{
    /// <summary>
    /// Window1.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class Window1 : Window
    {
        private string company = string.Empty;
        public string m_company
        {
            get
            {
                return company;
            }
            set
            {
                company = value;
            }
        }

        private string name = string.Empty;
        public string m_name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

        public Window1() : this("company", "name") { }

        public Window1(string company, string name)
        {
            //InitializeComponent();
            this.company = company;
            this.name = name;
        }
    }

    public class datas : ObservableCollection<Window1> { }

단순하게 객체 하나에 ObservableCollection에 모두 집어 넣는다는 것을 감을 잡을 수 있다.

다음은 XAML 코드이다.

<Window x:Class="WpfApplication5.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cs="clr-namespace:WpfApplication5"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <cs:datas x:Key="list">
            <cs:Window1 m_company="1번회사" m_name="first"/>
            <cs:Window1 m_company="2번회사" m_name="second"/>
            <cs:Window1 m_company="3번회사" m_name="third"/>
        </cs:datas>
    </Window.Resources>

    <StackPanel DataContext="{StaticResource list}" >
        <TextBlock Name="blah" FontSize="20" Margin="10,0,0,0"  Text="Company List:"/>
        <ListBox Width="260" Margin="10" ItemsSource="{Binding}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
                    <TextBlock Text="{Binding Path=m_company}" />
                    <TextBlock Text=" : " />
                    <TextBlock Text="{Binding Path=m_name}" />
                  </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>       
    </StackPanel>
</Window>

위에서 보면 리소스에 하나의 데이터 집합들이 있음을 볼 수 있다.

그리고 StackPanel 쪽에서 보면 DataContext를 위의 리소스 상의 키 값으로 물려주고 리스트 박스 쪽에 바인딩을 시켜 그 내용을 볼 수 있음을 확인 할 수 있다.

조금 응용을 해서 좀 더 이쁘게 보이려면 다음과 같이 하면 된다.

<DataTemplate>
       <Border Name="border" BorderBrush="Aqua" BorderThickness="1" Padding="5" Margin="5">
              <Grid>
                            <Grid.RowDefinitions><RowDefinition/><RowDefinition/></Grid.RowDefinitions>
                            <Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition /></Grid.ColumnDefinitions>
                            <TextBlock Grid.Row="0" Grid.Column="0" Text="Company:"/>
                            <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=m_company}" />
                            <TextBlock Grid.Row="1" Grid.Column="0" Text="Name:"/>
                            <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=m_name}"/>
              </Grid>
       </Border>
</DataTemplate>

[WPF] DataBinding WPF 2012. 3. 14. 16:40

데이터 바인딩은 컨트롤에 데이터를 채우고 동기화 시켜보면 그 내용을 확인 할 수 있다.

바인딩은 말 그대로 데이터를 연결하는 것이다.

다음 예제를 보면 확인 가능하다. 먼저 XAML 코드 아래 다음과 같이 디자인을 한다.

<Window x:Class="WpfApplication4.Window1"       
    xmlns:cs="clr-namespace:WpfApplication4"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="351" Width="500">
    <Window.Resources>
        <cs:NameAdds x:Key="names">
            <cs:NameAdd Name="first" Add="주소1"/>
            <cs:NameAdd Name="second" Add="주소2"/>
            <cs:NameAdd Name="third" Add="주소3"/>
        </cs:NameAdds>           
    </Window.Resources>
    <Grid x:Name="Maingrid" DataContext="{StaticResource names}" >
        <Grid.RowDefinitions>
            <RowDefinition Height="10*" />
            <RowDefinition Height="4*" />
            <RowDefinition Height="10*" />
            <RowDefinition Height="2*" />
            <RowDefinition Height="74*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="10*" />
            <ColumnDefinition Width="15*" />
            <ColumnDefinition Width="10*" />
            <ColumnDefinition Width="35*" />
            <ColumnDefinition Width="10*" />
        </Grid.ColumnDefinitions>
        <Label Grid.Row="2" Grid.Column="0" Name="label1" Content="성명 : " />
        <TextBox Grid.Row="2" Grid.Column="1"  Name="txtName" Text="{Binding Path=Name}" />
        <Label Grid.Row="2" Grid.Column="2" Name="label2" Content="주소 : " />
        <TextBox Grid.Row="2" Grid.Column="3"  Name="txtAddress" Text="{Binding Path=Add}" />
        <Button Grid.Row="0" Grid.Column="0" Name="insertbutton" Content="추가" Click="insertbutton_Click" Margin="3" ></Button>


        <ListBox Grid.Row="4" Grid.ColumnSpan="5" Name="list" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True"
                 FontSize="12" FontWeight="bold" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
            <TextBlock Text="{Binding Path=Name}" />
            <TextBlock Text=" :  " />
            <TextBlock Text="{Binding Path=Add}" />
          </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>


위에서 보면  xmlns:cs="clr-namespace:WpfApplication4" 와 같은 부분이 있다. 이는 XAML에서 cs 파일을 가져오기 위한 것인데 무작정 실행하려고 하면 되지 않는다. cs 파일을 정의 한 다음 빌드를 한번 꼭 해주자. 그렇지 않으면 어셈블리가 없다는 오류 메세지가 계속 나올 것이다.

다음은 cs 파일이다.

using System.ComponentModel;
using System.Collections.ObjectModel;


namespace WpfApplication4
{
    public partial class Window1 : Window
    {
        NameAdds nameadds;

        public Window1()
        {
            InitializeComponent();
            nameadds = new NameAdds();
            nameadds = (NameAdds)FindResource("names");
        }

        private void insertbutton_Click(object sender, RoutedEventArgs e)
        {
            nameadds.Add(new NameAdd());
        }
    }


    public class NameAdds : ObservableCollection<NameAdd> { }


    public class NameAdd : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void Notify(string strName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(strName));
            }
        }

        string name = string.Empty;
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                Notify("Name");
            }
        }

        string add = string.Empty;
        public string Add
        {
            get { return add; }
            set
            {
                add = value;
                Notify("Add");
            }
        }

        public NameAdd() : this("name", "address") { }
        public NameAdd(string name, string add)
        {
            this.name = name;
            this.add = add;
        }
    }
}

ObservableCollection과 INotifyPropertyChanged은 위에 using 된 부분을 참조 하여 이용한다.

이들은 각기 클래스 항목 변화에 의해 동적 컬렉션을 나타내는 것과 속성 값의 변화를 알리는 역할을 한다.

[WPF] Control WPF 2012. 3. 14. 15:33

기본적으로 많은 컨트롤들을 프로그래머라면 사용을 해 보았을 것입니다 하지만 WPF 상에서는 약간의 차이점이 존재하는데 이벤트, 마우스, 키보드 입력 등이 있습니다.

<Grid.ColumnDefinitions>
            <ColumnDefinition Width = "33*"/>
            <ColumnDefinition Width = "33*"/>
            <ColumnDefinition Width = "34*"/>
        </Grid.ColumnDefinitions>
        <Button Grid.Column="0" Height="100" Width="83">
            <TextBlock Width="95">TextBlock</TextBlock>
        </Button>
        <Button Grid.Column="1" Height="100" Width="83">
            <Image Source="/WpfApplication3;component/Image/Koala.jpg"/>
        </Button>
        <Button Grid.Column="2" Height="100" Width="83">
            <Grid Height="100" Width="83">
                <Grid.RowDefinitions>
                    <RowDefinition Height="50*"/>
                    <RowDefinition Height="30*"/>
                </Grid.RowDefinitions>
                <Image Source="/WpfApplication3;component/Image/Koala.jpg" Grid.Row="0" />
                <TextBlock Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center">코알라</TextBlock>
            </Grid>
        </Button>

위 코드를 실행 해 보면 앞에서 설명한 레이아웃을 조절하여 컨트롤 상의 레이아웃을 또 집어 넣어 변화 시키는 예제이다.

[WPF] Layout WPF 2012. 3. 14. 15:19

레이아웃은 알다시피 화면 구성요소들의 배치이다. 레이아웃을 정의 하도록 패널이라는 것이 존재하는데 이것은 컨트롤러들을 담을 수 있는 그릇이라 생각하면 된다.

다음 예제는 레이아웃에 대해 확인 할 수 있는 샘플이다.

<Grid.RowDefinitions>
            <RowDefinition Height=" 33*"/>
            <RowDefinition Height=" 33*"/>
            <RowDefinition Height=" 34*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="33*"/>
            <ColumnDefinition Width="33*"/>
            <ColumnDefinition Width="34*"/>
        </Grid.ColumnDefinitions>
        <Rectangle Fill="Red" Grid.Row="0" Grid.Column="0"/>
        <Rectangle Fill="Orange" Grid.Row="0" Grid.Column="1"/>
        <Rectangle Fill="Yellow" Grid.Row="0" Grid.Column="2"/>
        <Rectangle Fill="Green" Grid.Row="1" Grid.Column="0"/>
        <Rectangle Fill="Blue" Grid.Row="1" Grid.Column="1"/>
        <Rectangle Fill="DarkBlue" Grid.Row="1" Grid.Column="2"/>
        <Rectangle Fill="Purple" Grid.Row="2" Grid.Column="0"/>
        <Rectangle Fill="White" Grid.Row="2" Grid.Column="1"/>
        <Rectangle Fill="Black" Grid.Row="2" Grid.Column="2"/>

[WPF] XBAPs WPF 2012. 3. 14. 15:06
XBAPs는 XAML Browser Applications를 말한다. 이것은 웹 App와 윈도우 App 의 장점을 조합하여 새로운 App 구현을 하게 만든 것이다.

프로젝트를 만들 때 먼저 WPF 브라우저 응용 프로그램을 선택하여 프로젝트를 생성합니다.

다음으로 프로젝트에서 페이지를 추가하여 기본 작업을 구성 해 둡니다.

그리고 Image 폴더를 생성하여 임의의 그림 파일 3장을 설정 합니다.

다음에 각각 아래와 같은 코드들을 작성합니다. 코드를 작성하기 앞서 간단히 이야기 하자면

Window가 아닌 Page 로 작성되어 화면이 전환 되는 것을 확인 할 수가 있습니다.

Page1.XAML

<Grid.RowDefinitions>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="70*"/>
            <RowDefinition Height="20*"/>
        </Grid.RowDefinitions>
        <TextBlock Text="Test1" FontSize="20" HorizontalAlignment="Center" Grid.Row="0"/>
        <Image Grid.Row="1" Name="img1" Stretch="Fill" Source = "/WpfBrowserApplication1;component/Image/Tulips.jpg"/>
        <TextBlock Grid.Row="2" FontSize="20" HorizontalAlignment="Center">
            <Hyperlink NavigateUri="Page2.xaml"><TextBlock Text="Next->&gt;"/></Hyperlink>
        </TextBlock>

Page2.XAML

<Grid.RowDefinitions>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="70*"/>
            <RowDefinition Height="20*"/>
        </Grid.RowDefinitions>
        <TextBlock Text="Test2" FontSize="20" HorizontalAlignment="Center" Grid.Row="0"/>
        <Image Grid.Row="1" Name="img2" Stretch="Fill" Source = "/WpfBrowserApplication1;component/Image/Lighthouse.jpg"/>
        <TextBlock Grid.Row="2" FontSize="20" HorizontalAlignment="Center">
            <Hyperlink NavigateUri="Page1.xaml"><TextBlock Text="&lt;Back"/></Hyperlink>
            <Hyperlink NavigateUri="Page3.xaml"><TextBlock Text="Next&gt;"/></Hyperlink>
        </TextBlock>

Page3.XAML

<Grid.RowDefinitions>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="70*"/>
            <RowDefinition Height="20*"/>
        </Grid.RowDefinitions>
        <TextBlock Text="Test3" FontSize="20" HorizontalAlignment="Center" Grid.Row="0"/>
        <Image Grid.Row="1" Name="img3" Stretch="Fill" Source = "/WpfBrowserApplication1;component/Image/Hydrangeas.jpg"/>
        <TextBlock Grid.Row="2" FontSize="20" HorizontalAlignment="Center">
            <Hyperlink NavigateUri="Page2.xaml"><TextBlock Text="&lt;Back"/></Hyperlink>
        </TextBlock>
[WPF] 시작 WPF 2012. 3. 14. 14:38

WPF .NET Framework 3.x에 추가된 새로운 기술중 하나로, Windows Vista의 새로운 UX를 제공하기 위해 탄생되었습니다.

WPF에서는 그 핵심이 UX에 있다보니 기존 Window 프로그래밍과 다르게 디자인적인 측면이 많이 요구되어 디자이너와 협업을 하여 작업을 해야 합니다.
이 때 개발자와 디자이너가 소통할 수 있는 중간언어를 사용해서 디자인과 코딩 작업을 병행할 수 있다면 커뮤니케이션 면, 생산성 면에서 좋은 효과를 거둘 수 있을 것입니다. 이를 위해 Microsoft사는XAML(Extensible Application Markup Language)이라고 하는 새로운 MarkUp Language를 발표하여 UI를 표현하기 위한 XAML언어를 이용하여 개발자와 디자이너가 모두 사용 가능한 형태의 중간 언어를 제공하게 되었습니다.

정리를 하자면 WPF는 Windows vista의 새로운 UX(User Experience:사용자 경험)를 제공하기 위해 탄생되었으며 이를 위해 개발자와 디자이너의 협업을 위한 XAML이라는 MarkUp Language로 개발자와 디자이너가 공동으로 작업할 수 있는 환경이 만들어지게 된것 입니다.

다음은 맛보기!!

<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" WindowStartupLocation="CenterScreen">
    <Grid>

        <Button Name="btn" Margin="42,17,44,0" FontSize="10" Background="AliceBlue" Content="TEST" Height="74" VerticalAlignment="Top" />
    </Grid>
</Window>

XAML을 위와 같이 작성하고 실행을 해 보면 폼에 버튼이 하나 나타난 것을 확인 할 수가 있다.