WPF에서 많은 컨트롤들을 사용할 수 있다. 근데, 그 컨트롤들의 배경색이나 끝마감, 텍스트의 폰트 크기등을 미리 정의할 수 있다. (CSS에 대응된다고 생각하면 쉽다.)
스타일의 장점은
1. 화면에 보이는 UI컨트롤들의 특징을 공통되게 적용할 수 있다. 즉, 일괄 적용이 필요한 것을 해당 style에서 수정하면 된다. (즉, 일이 엄청나게 줄어든다.)
2. 상속이 가능하므로, 상속을 사용하여 일을 더 줄일수 있다.
<Window blabla(namespace선언등 여러가지)>
<Window.Resources>
<Style x:Key="MyBaseStyle" TargetType="{x:Type Button}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Background" Value="Red" />
</Style>
<Style
x:Key="MyChildStyle" //이 스타일의 키 이름은?
TargetType="{x:Type Button}" //어느 컨트롤에 적용할것인지?
BasedOn="{StaticResource ResourceKey=MyBaseStyle}" //혹시 상속받는다면 부모 키 이름은?
>
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</Window.Resources>
<StackPanel>
<Button x:Name="BaseBtn" Style="{StaticResource ResourceKey=MyBaseStyle}" Content="BtParent" />
<Button x:Name="ChildBtn" Style="{StaticResource ResourceKey=MyChildStyle}" Content="BtChild" />
</StackPanel>
</Window>
위와 같이 선언하면 스타일이 만들어진다. BasedOn 은 상속받고자 하는 부모 스타일의 키 이름을 적어주면 된다. (없으면 안써도 된다.)
지금 MyChildStyle은 MyBaseStyle 의 속성을 상속받았다. 그래서, MyChildStyle은 VerticalAlignment는 Top, HorizontalAlignment는 Center로 설정되어있는거다. 버튼의 배경색은 Red인거고.
적용하는 방법은 StackPanel에 붙인것 처럼 컨트롤에서 Style="{StaticResource Resourcekey=키이름}" << 이렇게 선언하면 스타일이 적용된다.
다만, 주의할 것은.. 스타일에 선언한 TargetType와 해당 스타일을 사용하는 컨트롤의 Type이 같을 것!
즉, 스타일의 TargetType이 Textblock인데, 그 스타일을 Button에다가 적용하려들지 말것.. (당연히...)
그리고 Style은 Resource영역에 선언 가능한데.. 이걸 별도의 Resource파일에 선언하고, 각 xaml에서 해당 resource를 import해서 사용할 수 있다.
예를들어 내가 ./Resources/BaseStyle.xaml 이라는 resource파일을 만들었다고 하면.. 각 UI를 담당한 xaml에서는 다음과 같이 사용할 수 있다.
<Window namespaces...blabla>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MyAssembly;Resources/BaseStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
</Window>
위와 같이 ResourceDictionary.MergedDictionaries안에 포함할 ResourceDictionary이름을 적어주면 된다.
Source는 상대경로, 절대경로 다 가능하다. 상대경로로 한다면.. pack://...; 부분을 지우고, ../Resources/ << 이런식으로 작성해주면 된다. 다만, 절대경로로 처리하는 것이 나중에 좀 더 깔끔해진다. 상대경로는 폴더 위치가 변경되거나 하면.. 저 경로를 다시 다 맞추어야한다. 절대경로를 추천..
참.. 저 ResourceDictionary끼리도 참조 가능하다.
그래서 ResourceDictionary에 어디에는 Button Style만, 어디에는 TextBox Style만, 또 어디에는 Color ( Brush)만 정의하고, 필요에 따라 각각의 ResourceDictionary를 import하여 새로운 ResourceDictionary를 만들고, 그걸 xaml에서 가져다 쓰도록 만드는 것도 가능하다.
그리고 Resource를 StaticResource로 찾아서 가져오도록 해 두었다. 필요에 따라 DynamicResource로 하는 것도 가능하다. Dynamic은 말 그대로 동적으로 리소스를 찾는거.. 컴파일타임에 정의하지 않기에 스타일같은거 반영이 디버깅하면서 바로 확인은 잘 안된다. 그리고, 리소스를 불러올 때 해당 리소스가 없으면? 문제발생.
하지만, 동적으로 리소스가 변경이 가능하다는 장점이 있다.
Static은 그 반대이다. 컴파일 타임에 리소스를 적재하니까 속도는 좀 더 빠르다. 그리고, 개발하면서 변경되는 사항은 바로바로 반영 및 확인이 쉽다. 하지만 정적이다.
그리고.. Style적용 시, Style="{StaticResource ResourceKey=키이름}" 이런식으로 작성하고, Style선언 시, TargetType에 {x:Type Button} 이런식으로 작성해 두었는데.. Style="{StaticResource 키이름}", TargetType="{Button}" 으로 해도 되긴 한다. 근데, 조금 더 명확하게 누구를 찾아라! 라고 지정하기위해 항상 작성하던 습관이 있어서 ResourceKey=키이름 << 이런식으로 작성한다. 가급적이면 저렇게 명확하게 해주세요. :)
댓글