StaticResource와 DynamicResource에 대한 이야기를 시작하기 전에

우선적으로 Resource가 무엇인지 궁금한 사람들이 많을 거라고 생각합니다.

 

- Resource

WPF에서 리소스(Resource)란 보통 한 번 이상 혹은 자주 사용하기를 원하는 자원을 말합니다.

리소스는 필요할 때 재사용할 수 있도록 임시로 어딘가에 저장됩니다.

(CPU의 캐시 된 메모리와 비슷하다고 생각하시면 됩니다!)

 

모든 객체는 리소스로 정의될 수 있으며, 고유 키는 XAML 리소스에 지정됩니다.

우리는 해당 키를 이용해 StaticResource 혹은 DynamicResource 태그를 사용하여 참조할 수 있습니다. 

 

- 왜 리소스를 사용할까?

1. 재사용성, 공통 파일에서 단 한 번만 정의하고 여러 XAML에서 사용할 수 있다.

2. 사용범위가 전역, 즉 전체 응용프로그램인 경우 데이터를 로컬로 저장.

3. 그리도, 스택 패널등 같은 패널 내에서 정의 가능.

 

이러한 장점들이 존재합니다!

리소스의 활용을 극대화 하기위하여

WPF에는 두 가지 유형의 리소스가 있습니다.

- StaticResource와 DynamicResource

개발자라면 Static과 Dynamic이라는 단어를 굉장히 많이 접해보았겠죠?

정적(Static) 동적(Dynamic)의 의미를 갖고 있습니다.

위에 앞서 설명했듯이 리소스는 정적 또는 동적으로 참조될 수 있습니다.

 

StaticResource와 DynamicResource의 가장 큰 차이는 참조 요소에 의해 리소스가 검색되는 방식에 있습니다.

 

StaticResource(정적 리소스)는 참조 요소에 의해 한번만 검색되며 리소스의 전체 수명에 사용됩니다.

즉, 페이지를 새로 로드하는 것과 같은 런타임 동작을 기반으로 다시 검색되지 않습니다.

반복해서 검색되지 않기 때문에 성능적인 우위가 있겠죠?

 

DynamicResource(동적 리소스)는 런타임 시 변경될 여지가 있는 리소스에 사용됩니다.

리소스가 참조될 때마다 리소스를 다시 읽어오기 때문에 StaticResource에 비하여 성능 저하가 발생할 수 있습니다.

 

우선 StaticResource와 DynamicResource의 사용 예시를 확인해봅시다.


- StaticResource

<Button Style="{StaticResource ResourceKey}"></Button>

- DynamicResource

<Button Style="{DynamicResource ResourceKey}"></Button>

 

이렇게만 봐서는 잘 모르겠죠?

 

실제로 버튼을 만들어서 어떤 차이가 있는지 알아봅시다 :)

 

Static / Dynamic으로 나누어 2개의 버튼을 만들어줄 거예요.

 

 

- 예제


[MainWindow.xaml]

 <Button Grid.Row="1" Grid.Column="1" Content="Static"></Button>
 <Button Grid.Row="3" Grid.Column="1" Content="Dynamic"></Button>

-버튼 생성

전체 코드를 보고 싶으신 분은 더보기를 눌러주세용 :D

더보기

전체 코드

<Window x:Class="StaticAndDynamicResource.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:StaticAndDynamicResource"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="10"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="10"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="10"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Button Grid.Row="1" Grid.Column="1" Content="Static"></Button>
        <Button Grid.Row="3" Grid.Column="1" Content="Dynamic"></Button>
    </Grid>
</Window>

 

 

예를 쉽게 들기 위하여 App.xaml을 사용합니다.

App.xaml을 쉽게 설명하면 해당 xaml에서 지정해준 스타일은 전역에 세팅이 된답니다!

아직 저도 이쪽에 대한 이해가 낮은 편이라 완벽하게 숙지가 된다면 추가로 포스팅할게요 :)

 

[App.xaml]

<Application.Resources>
        <Style TargetType="Button">
            <Setter Property="Background" Value="Black"/>
            <Setter Property="Foreground" Value="white"/>
        </Style>
</Application.Resources>

위 코드와 같이 스타일 설정을 해준다면

 

-App.xaml에서 스타일 지정

어라?

우리는 분명 MainWindow.xaml에서 따로 스타일을 지정해준 적이 없는데 배경과 글자색이 변경되었네요!

그 원리는 TargetType에 있습니다!

 

[App.xaml]

<Style TargetType="Button">

해당 부분의 TargetType을 Button으로 설정해주었기 때문에

앞으로 생성해주는 모든 버튼은 저희가 설정해준 스타일을 적용하여 생성됩니다!

 

이쯤에서 이런 의문이 들겠죠?

흠.. 이런 스타일의 버튼을 많이 사용하긴 할 건데.. 전부 이런 스타일은 싫어요!

 

그렇다면 App.xaml에서 2가지의 스타일을 지정하고 MainWindow.xaml에서 각각의 스타일을 입혀주면 어떨까요?

 

[App.xaml]

<Style TargetType="Button" x:Key="StaticStyle">
	<Setter Property="Background" Value="Black"/>
	<Setter Property="Foreground" Value="White"/>
</Style>
<Style TargetType="Button" x:Key="DynamicStyle">
	<Setter Property="Background" Value="Blue"/>
	<Setter Property="Foreground" Value="White"/>
</Style>

[MainWindow.xaml]

<Button Grid.Row="1" Grid.Column="1" Content="StaticResource Button" Style="{StaticResource StaticStyle}"/>
<Button Grid.Row="3" Grid.Column="1" Content="DynamicResource Button" Style="{DynamicResource DynamicStyle}"/>

첫 번째 버튼에는 Style="{StaticResource StaticStyle}"

두 번째 버튼에는 Style="{DynamicResource DynamicStyle}"

을 지정해주고 App.xaml에서 2가지의 스타일과 각 버튼의 스타일에 적용된 이름을 x:key로 지정해주었어요

결과는 어떨까요?

 

 

두 가지의 스타일이 잘 적용되었죠?

언뜻 보면 맞는 것 같지만 엄밀히 말하면 잘못된 사용법이라고 볼 수 있어요.

 

이런 식으로 사용할 거면 App.xaml에 굳이 스타일을 지정해두고 사용하는 의미가 없겠죠!

잘 이해가 안 가시나요?

StaticResource와 DynamicResource의 사용방법은 무궁무진 하지만 제가 자주 사용하는 방법을 알려드릴게요! 

 

 

드디어 이제 우리가 앞서 배운 Static과 Dynamic의 활용법을 배울 때네요!

StaticResource부터 볼까요?

StaticResource는 앞서 말했듯이 정적인 리소스예요!

 

[MainWindow.xaml]

 <Button Grid.Row="1" Grid.Column="1" Content="Static"></Button>
 <Button Grid.Row="3" Grid.Column="1" Content="Dynamic"></Button>

다시 처음으로 돌아와 기본 버튼만 생성해 놓았습니다.

여러분이 잘 아는 가장 기본 형태 (회색 바탕에 검정 폰트)의 버튼이 생성되었겠죠?

 

이제 App.xaml에서 StaticResource Style을 설정해봅시다.

 

[App.xaml]

 

<Style TargetType="{x:Type Control}" x:Key="StaticStyle">
	<Setter Property="Background" Value="Black"/>
	<Setter Property="Foreground" Value="White"/>
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource StaticStyle}"></Style>

무언가 많이 변한 게 보이시나요?

우선 첫 번째 스타일을 봅시다!

<Style TargetType="{x:Type Control}" x:key="StaticStyle"> 이 부분을 잘 보셔야 해요.

스타일의 타깃 타입을 Control로 설정한 이유는 바로 여기에 있습니다.

 

Control Class
Control Class에 속해있는 Foreground 와 Background

 

우리는 Button의 Background와 Foreground를 변경하려 했죠?

Control클래스가 Background와 Foreground의 부모이기 때문에 TargetType에 Control을 설정해주면

Control클래스의 자식들을 얼마든지 가져다 쓸 수 있다는 장점이 있어요 :)

이 부분에 대해서 이해가 어려우시면 댓글 남겨주세요!

 

두 번째로 봐야 할 것은 x:key="StaticStyle"

StaticStyle은 제가 임의로 설정해준 이름입니다! 여러분이 사용할 이름을 편하게 적어주시면 될 것 같아요

이 key값은 위 코드 중 마지막 스타일에서 재사용됩니다!

 

<Style TargetType="{x:Type Button}" BasedOn="{StaticResource StaticStyle}"></Style>

 

해당 코드를 보시면 TargetType에는 우리가 실제로 사용할 타입 --> Button이 입력되었고

BasedOn 즉 모든 버튼의 기본 스타일을 {StaticResource StaticStyle}로 설정한다는 의미예요

여기서 StaticStyle이라는 이름은 여러분이 지정해준 key값입니다!

이해가 가시나요?

 

결과부 터봅시다!

 

 

StaticResource로 모든 버튼을 통일시킴

 

짜잔! 모든 버튼의 Base가 우리가 설정해준 검정 배경에 하얀 글씨로 바뀌었네요!!

우리는 모든 버튼에 StaticResource를 사용하였기 때문에 이 버튼은 런타임과 동시에 메모리가 할당이 되고

프로그램이 종료될 때까지 수명이 다하지 않아요!

즉 변경이 되지 않고 언제나 해당 상태를 유지해야 할 때 StaticResource를 사용하시면 됩니다!

 

어..? 그런데 우리는 DynamicResource로 버튼을 따로 컨트롤해주고 싶어요!

 

이럴 때 제가 사용하는 방법은 리소스 사전을 이용하는 거예요!

 

프로젝트에서 리소스 사전을 추가해주자

 

Dictionary1.xaml을 생성해주고 이곳에 원하는 스타일을 추가해봅시다.

 

[Dictionary1.xaml]

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:ResourcePractice">

    <Style TargetType="{x:Type Button}" x:Key="DynamicStyle">
        <Setter Property="Background" Value="Blue"/>
        <Setter Property="Foreground" Value="White"/>
    </Style>
</ResourceDictionary>

StaticResource와 형태가 굉장히 흡사하죠?

 

그렇다면 이 스타일은 어떻게 적용할까요?

 

App.xaml로 돌아와 위에 적용해준 Dictionary1.xaml을 참조받아옵시다.

 

[App.xaml]

 

<ResourceDictionary.MergedDictionaries>
	<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>

어때요 감이 잡히시나요?

App.xaml에서 Dictionary1.xaml을 참조받아왔어요!

이제 어느 MainWindow.xaml에서도 App.xaml을 통해 Dictionary1.xaml에 있는 스타일을 가져올 수 있겠죠?

 

MainWindow.xaml에서 스타일을 마무리 지어봅시다.

 

[MainWindow.xaml]

<Button Grid.Row="3" Grid.Column="1" Content="DynamicResource Button" Style="{DynamicResource DynamicStyle}"/>

 

스타일이 잘 적용된것을 볼 수 있다!

 

어때요? 감이 오시나요?

 

조금 난해하기도 하고 굳이 이렇게 사용해야 하나?라는 의문이 드시는 분도 많을 거라 생각해요.

사용 방법은 무궁무진하지만 굳이 이렇게 사용한 이유는 가장 간결하게 코드 구성을 하기 위해서예요.

 

StaticResource는 전역에 원하는 Base Style을 쫙 뿌려주고

그중 고치고 싶은 부분만 DynamicResource로 컨트롤해주는 방식이랍니다 :)

 

첫 게시글이라 아직 많이 난해하고 저도 정리가 조금 어렵지만

부디 이 글을 보시고 WPF에 대하여 재미를 느끼셨으면 좋겠어요!

 

아직 저도 초보 개발자인지라 많이 부족하니

언제든지 태클과 훈수 환영합니다!

 

모르는 부분이 있다면 댓글 남겨주세요!

 

앞으로도 힘내서 포스팅할게요:D

 

다들 좋은 하루 보내세요!


 

 

 

 

 

728x90

+ Recent posts