|
클래스 이름 |
설명 |
Application |
응용 프로그램을 캡슐화 |
FrameworkElement |
이벤트 및 메소드 집합을 제공하는 클래스 |
FrameworkContentElement |
ContentElement 기본 클래스의 WPF 프레임워크 수준 구현 및 확장 |
예제) 서로 다른 Resources 컬렉션에서 같은 키 사용, 컨트롤을 리소스로 정의
Window1.xaml |
<StackPanel Name="parent"> <StackPanel.Resources> <Button x:Key="btn" FontSize="24" Content="Resource Button"></Button> <SolidColorBrush x:Key="brushtext" Color="Green"></SolidColorBrush> </StackPanel.Resources> <StackPanel Name="child"> <StackPanel.Resources> <SolidColorBrush x:Key="brushtext" Color="Red"></SolidColorBrush> </StackPanel.Resources> <Button Margin="24" Content="Child" HorizontalAlignment="Center" Foreground="{StaticResource brushtext}"></Button> </StackPanel> <Button Content="Parent" HorizontalAlignment="Center" Foreground="{StaticResource brushtext}"></Button> <StaticResource ResourceKey="btn"></StaticResource> </StackPanel> |
편의상 StackPanel을 사용했습니다. parent StackPanel에 단색으로 영역을 칠하는 SolidColorBrush와 Button을 리소스로 정의하였습니다.
child의 StackPanel에도 SolidColorBrush를 리소스로 정의하였는데 여기서 사용한 키 값을 parent의 StackPanel의 키 값과 같은 값을 주었습니다. 실행을 해보면 다른 Resources 컬렉션이므로 상관 없으며 리소스의 적용 범위도 확인할 수 있습니다.
Button리소스의 경우 동일한 패널 속에서 다른 것의 자식이나 다른 패널의 자식이 될 수 없습니다. 또한 StaticResource 엘리먼트로 이 Button을 참조하는 순간 이 Button에 대해 어떤 것도 변경할 수 없기 때문에 리소스로 Button을 생성하는 것은 특별한 장점이 없습니다.
결과화면 |
|
2. 마크업 확장
리소스를 참조하기 위해 사용하는 것으로 마크업 확장 태그에는 정적 리소스, 동적 리소스, x:Static 마크업 확장이 있습니다. 중괄호를 사용하여 마크업 확장의 존재를 알려줍니다.
종류 |
사용 |
정적 리소스 |
{StaticResource key} |
동적 리소스 |
{DynamicResourc key} |
정적 프로퍼티 및 필드 |
{x:Static SomeClass.SomeStaticProp} |
시스템 리소스 |
{x:Static System.Colors.ActiveCaptionBrushEKey} |
정적 리소스와 동적 리소스를 사용하는 경우는 다음과 같습니다.
정적 리소스 |
동적 리소스 |
처음으로 참조한 리소스의 값을 변경할 의도가 없는 경우 |
런타임 시에 값을 알 수 있는 경우 |
페이지나 응용 프로그램에 리소스를 모아 주로 사용할 경우 |
사용자 지정 컨트롤에 대한 테마 스타일을 만들거나 참조하는 경우 |
|
응용 프로그램 수명 동안 ResourceDictionary의 내용을 조정하려는 경우 |
|
참조된 리소스가 즉시 사용되지 않을 경우 |
|
setter 값을 테마 또는 다른 사용자 설정의 영향을 받는 다른 값에서 가져올 수 있는 스타일을 만드는 경우 |
간단히 말해서 정적 리소스와 동적 리소스의 차이는 정적 리소스는 페이지가 로드 될 때 XAMLdptj 참조가 로드 되지만, 동적 리소스는 리소스를 사용하기 전까지는 참조를 로드하지 않습니다.
예제) 리스트박스의 선택한 숫자 아이템으로 글씨 크기 변경
Window1.xaml |
<Window.Resources> <Style TargetType="TextBlock" x:Key="FontStyle"> <Setter Property="FontSize" Value="20" /> <Setter Property="Foreground" Value="Blue" /> </Style> </Window.Resources> <StackPanel> <ListBox Name="lbox_fsize" electi[안내]태그제한으로등록되지않습니다-xxonChanged="lbox_fsize_Selecti[안내]태그제한으로등록되지않습니다-xxonChanged"> <ListBoxItem Content="20" /> <ListBoxItem Content="30" /> <ListBoxItem Content="40" /> </ListBox> <TextBlock Name="sbox" Style="{StaticResource FontStyle}" Text="난 가만히" /> <TextBlock Name="dbox" Style="{DynamicResource FontStyle}" Text="난 변신해" /> </StackPanel> |
Style을 리소스로 정의하였으며 ListBox와 두 개의 TextBlock이 있습니다. sbox는 Style 속성을 정적 리소스, dbox는 동적 리소스를 참조합니다.
다음은 Selecti[안내]태그제한으로등록되지않습니다-xxonChanged 이벤트 처리 입니다.
Window1.xaml.cs |
private void lbox_fsize_Selecti[안내]태그제한으로등록되지않습니다-xxonChanged(object sender, Selecti[안내]태그제한으로등록되지않습니다-xxonChangedEventArgs e) { int cnt = 0; Style mystyle = Resources["FontStyle"] as Style; Style chstyle = new Style(); ListBoxItem lvi = lbox_fsize.SelectedItem as ListBoxItem;
double fsize = double.Parse(lvi.Content.ToString());
foreach (Setter s in mystyle.Setters) { if (cnt == 0) { chstyle.Setters.Add(new Setter(s.Property, fsize)); } else { chstyle.Setters.Add(new Setter(s.Property, s.Value)); } cnt++; } Resources["FontStyle"] = chstyle; } |
mystyle은 키 값이 FontStyle로 된 Style을 참조하고 ListBox에서 선택한 아이템을 숫자로 바꾸기 위해서 double.Parse를 이용합니다. 그리고 foreach문을 돌면서 동적 리소스 참조한 UI 개체의 Style을 다시 설정해 줍니다.
결과화면 |
|
3. x:Static 마크업
정적 필드나 프로퍼티 리소스를 사용한는 경우, 리소스의 키 값으로 System.Colors, System.Fonts, System.Parameters 클래스의 요소로 만드는 시스템 리소스일 경우 사용하는 태그 확장으로 여기서는 정적 필드나 프로퍼티로 리소스를 사용하는 예제 설명만 하겠습니다.
Contents.cs |
public static class Contants { public static readonly FontFamily fnfm = new FontFamily("Times New Roman Italic"); public static double FontSize { get { return 34.5; } } } |
글꼴과 관련된 FontFamily는 정적 필드로 크기는 정적 프로퍼티로 작성하였습니다.
Window1.xaml |
<Window x:Class="wpf2.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:src="clr-namespace:wpf2" Title="Window1" Height="300" Width="300"> <TextBlock FontSize="{x:Static src:Contants.FontSize}" > <TextBlock.FontFamily> <x:Static Member="src:Contants.fnfm"></x:Static> </TextBlock.FontFamily>Properties from<LineBreak/>Static Fields </TextBlock> </Window> |
src(다른 이름을 사용해도 상관 없음)를 CLR 네임스페이스 clr-namespace:wpf2와 연결시킨 XAML파일 입니다.이 파일은 x:Static 마크업 확장으로 프로퍼티에 접근을 합니다.
FontSize의 경우에는 프로퍼티 속성 문법, FontFamily는 프로퍼티 얼라인먼트 문법을 사용하였습니다.
결과화면 |
|
4. 리소스 사전
리소스만 따로 보관하기위 위해 ResourceDictionary.xaml을 이용합니다.
Dictionary1.xaml |
<SolidColorBrush x:Key="MyBrush1" Color="Blue"/> <SolidColorBrush x:Key="MyBrush3" Color="Green" /></Canvas> |
Dictionary2.xaml |
<SolidColorBrush x:Key="MyBrush2" Color="Brown" /> |
ResourceDictionary에는 여러 개의 리소스를 보관할 수 있습니다.
ResourceDictionary 작성이 끝났다면 여기서는 Application의 정의 파일 속에 포함된 리소스 절에 ResourceDictionary, 엘리먼트를 사용하겠습니다.
다수의 Dictionary 개체 컬렉션을 파일 이름으로 참조하는 MergedDictionary 프로퍼티를 정의합니다.(Dictionary 개체가 하나라면 굳이 MergedDictionary 프로퍼티 정의가 필요없이 ResourceDictionary 개체 내부에 바로 참조하면 됩니다.)
App.xaml (Dictionary 개체가 하나일 경우) |
<Application.Resources> <ResourceDictionary Source="Dictionary1.xaml"> </ResourceDictionary> </Application.Resources> |
App.xaml (Dictionary 개체가 여러 개일 경우) |
<Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Dictionary1.xaml" /> <ResourceDictionary Source="Dictionary2.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> |
UI에서의 리소스 참조는 앞에서 사용했던 방법들과 같다.