WPF

[WPF] WPF Application(3) - 리소스

귀뚜래미 2022. 9. 6. 16:32
728x90

 

- WPF에서는 원하는 모든 데이터를 리소스 형태로 저장하여 컨트롤이나 윈도우를 지역적으로 저장하거나 전체 애플리케이션을 전역으로 저장할 수 있다.

- 여기서 데이터는 실제 정보일 수도 있고 WPF 컨트롤들의 계층구조일 수도 있다.

 

- 리소스는 x:Key 속성으로 키를 받는다. 키를 이용해 애플리케이션 내 다른 위치에 있는 값을 참조할 수 있다.

- 키는 markup extension인 StaticResource와 결합되어있다.

 

 

StaticResource와 DynamicResource

- StaticResource의 경우 XAML이 로드될 때 단 한번 할당된다는 것이 주요 특징이다.

- StaticResource를 사용하면 나중에 리소스가 변경되더라도 변경사항이 반영되지 않는다.

 

- DynamicResource는 실제 필요할 때마다 할당한다. 리소스가 변경될 때 마다 반복해서 할당할 수 있다.

- DynamicResource는 디자인할 때 존재하지 않았던 리소스들도 사용할 수 있다.

 

 

  Local Resource와 Application Resource

- 하나의 특정 컨트롤을 위한 리소스가 필요할 경우 윈도우가 아닌 컨트롤에 추가해서 지역적으로 사용할 수 있다.

- 기존 윈도우의 무든 부분에서 리소스에 접근할 수 있는 것에 대해 작동 방식은 동일하나 유일한 차이점은 생성된 컨트롤 범위 내에서만 접근할 수 있다는 것이다.

<StackPanel Margin="10">
    <StackPanel.Resources>
        <sys:String x:Key="ComboBoxTitle">Items:</sys:String>
    </StackPanel.Resources>
    <Label Content="{StaticResource ComboBoxTitle}" />
</StackPanel>

- 이 경우 StackPanel에 리소스를 추가하고 하위 컨트롤인 Label에서 추가한 리소스를 사용했다.

- StackPanel 내 다른 컨트롤도 마찬가지로 이 리소스를 사용할 수 있으며 하위 컨트롤의 하위 컨트롤도 사용할 수 있다.

- 그러나 StackPanel 외부에서는 접근이 불가능하다.

 

- 여럿의 윈도우에서 리소스에 접근해야 하는 경우도 가능하다.

- 윈도우나 WPF 컨트롤이 리소스를 포함할 수 있는 것 처럼 App.xaml 파일도 리소스를 포함할 수 있다.

- App.xaml 파일에 리소스를 저장하면, 전역적으로 프로젝트 내 모든 윈도우와 컨트롤에서 접근할 수 있다.

- 윈도우에 리소스를 저장하고 사용하는 방식과 동일하게 작동한다.

 

<Application x:Class="WpfTutorialSamples.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             StartupUri="WPF application/ExtendedResourceSample.xaml">
    <Application.Resources>
        <sys:String x:Key="ComboBoxTitle">Items:</sys:String>
    </Application.Resources>
</Application>

- WPF는 주어진 리소스를 찾기 위해 자동으로 로컬 컨트롤에서 윈도우로, App.xaml 로 범위를 올려간다.

 

 

 

코드 비하인드의 리소스

- 코드 비하인드에서도 리소스에 접근할 수 있으며 몇몇 경우 더 유용할 수 있다.

 

App.xaml

<Application x:Class="WpfTutorialSamples.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             StartupUri="WPF application/ResourcesFromCodeBehindSample.xaml">
    <Application.Resources>
        <sys:String x:Key="strApp">Hello, Application world!</sys:String>
    </Application.Resources>
</Application>

Window

<Window x:Class="WpfTutorialSamples.WPF_Application.ResourcesFromCodeBehindSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="ResourcesFromCodeBehindSample" Height="175" Width="250">
    <Window.Resources>
        <sys:String x:Key="strWindow">Hello, Window world!</sys:String>
    </Window.Resources>
    <DockPanel Margin="10" Name="pnlMain">
        <DockPanel.Resources>
            <sys:String x:Key="strPanel">Hello, Panel world!</sys:String>
        </DockPanel.Resources>

        <WrapPanel DockPanel.Dock="Top" HorizontalAlignment="Center" Margin="10">
            <Button Name="btnClickMe" Click="btnClickMe_Click">Click me!</Button>
        </WrapPanel>

        <ListBox Name="lbResult" />
    </DockPanel>
</Window>

코드 비하인드

using System;
using System.Windows;

namespace WpfTutorialSamples.WPF_Application
{
	public partial class ResourcesFromCodeBehindSample : Window
	{
		public ResourcesFromCodeBehindSample()
		{
			InitializeComponent();
		}

		private void btnClickMe_Click(object sender, RoutedEventArgs e)
		{
			lbResult.Items.Add(pnlMain.FindResource("strPanel").ToString());
			lbResult.Items.Add(this.FindResource("strWindow").ToString());
			lbResult.Items.Add(Application.Current.FindResource("strApp").ToString());
		}
	}
}

실행 결과 버튼을 클릭하면 ListBox에 

Hello, Panel world!

Hello, Window world!

Hello, Application world!

메세지가 출력된다.

 

- 코드 비하인드에서는 버튼의 클릭 이벤트를 다룬다. 위의 결과와 같이 각각의 문자열 텍스트를 추가한다.

- FindResource() 메서드를 사용해 리소스를 찾으면 object로 리턴한다.

- 이후 ToString() 메서드를 사용해 string으로 변환한다.

 

- 이미 알고 있는 곳에서 리소스를 찾는 것이 일반적이나, 리소스를 찾지 못하면 계층 구조를 따라 검색한다.

- 검색은 트리구조의 아래방향으로 진행하지 않는다. 리소스가 컨트롤에 지역적으로, 또는 윈도우에 정의되어 있으면 애플리케이션 레벨부터 검색해서는 찾을 수 없다.

728x90