[WPF] 공공데이터 포털 API 이용 클라이언트 구현 Part 3

이미지
그룹핑 ListViewItem 그룹핑 할 수 있습니다. 먼저 CheckBox에 Checked 이벤트를 통해 그룹핑을 추가하고 RemoveChecked 이벤트를 통해 그룹핑을 제거 할 수 있도록 CheckBox를 선언 합니다. 1: <!-- Group CheckBox --> 2: <CheckBox Grid.Column="0" 3: Grid.Row="0" 4: Checked="AddGrouping" 5: Unchecked="RemoveGrouping">Group by Name</CheckBox> 그룹 스타일 선언 GroupStyle 속성에 ContainerStyle 속성을 이용해 Style을 지정 합니다. Expander 컨트롤을 이용해 아파트명과 그룹 아이템의 개수를 Expander Header에 표시 하도록 ControlTemlate를 선언 합니다. 1: <!-- Group Style --> 2: <ListView.GroupStyle> 3: <GroupStyle> 4: <GroupStyle.ContainerStyle> 5: <Style TargetType="{x:Type GroupItem}"> 6: <Setter Property="Margin" Value="0,0,0,5" /> 7: <Setter Property="Te...

WPF Resources

Binary Resources

이진 리소스는 세 가지 방법으로 패키지화 할 수 있습니다.
  • 어셈블리 내부에 포함
  • 컴파일 할 때 응용 프로그램에 알려진 느슨한 파일
  • 컴파일 할 때 응용 프로그램에 알려지지 않은 느슨한 파일

Defining Binary Resources 

이진 리소스를 정의하는 일반적인 절차는 파일을 Visual Studio 프로젝트에 추가하고 그림과 같이 img1.jpg라는 이미지에 대해 속성 표에서 적절한 빌드 동작을 선택하는 것입니다.


Visual Studio는 WPF 응용 프로그램에 대한 몇 가지 빌드 동작을 지원하며이 중 두 가지는 이진 리소스와 관련이 있습니다.
  • Resource - 리소스를 어셈블리 (또는 문화권 별 위성 어셈블리)에 포함합니다.
  • Content- 리소스를 느슨한 파일로 유지하지만 파일의 존재 및 상대 위치를 기록하는 어셈블리 (AssemblyAssociatedContentFile)에 사용자 지정 특성을 추가합니다.

Accessing Binary Resources

WPF는 코드 또는 XAML에서 유니폼 리소스 식별자로 액세스 할 수있는 메커니즘을 제공합니다 (URI). XAML의 URI 문자열에 대한 기본 옵션이 요약되어 있습니다. 이러한 옵션 중 일부는 부분 신뢰 응용 프로그램에서 사용할 수있는 것은 아닙니다.

If the URI Is... The Resource Is...
logo.jpg 현재 어셈블리에 포함되어 있거나 현재 XAML 페이지 또는 어셈블리와 나란히 느슨하게되어 있습니다 (프로젝트의 Content으로 표시된 경우에만 후자)
A/B/logo.jpg 컴파일 할 때 정의 된 내부 하위 폴더 (A\B) 구조를 사용하거나 현재 XAML 페이지 또는 어셈블리와 관련하여 느슨한 A\B 하위 폴더를 사용하여 현재 어셈블리에 포함됩니다 (프로젝트의 Content으로 표시된 경우에만 후자의 경우)
c:\temp\logo.jpg 로컬 c:\temp 폴더
file://c:/temp/logo.jpg 로컬 c:\temp 폴더
\\pc1\images\logo.jpg \\pc1\images UNC 공유
http://adamnathan.net/logo.jpg adamnathan.net 웹 사이트에서 호스팅
/MyDll;Component/logo.jpg MyDll.dll 또는 MyDll.exe라는 다른 어셈블리에 포함
/MyDll;Component/A/B/logo.jpg 컴파일 할 때 정의 된 내부 하위 폴더 구조 (A\B)를 사용하여 MyDll.dll 또는 MyDll.exe라는 다른 어셈블리에 포함
pack://siteOfOrigin:,,,/logo.jpg 원본 사이트
pack://siteOfOrigin:,,,/A/B/logo.jpg A\B 하위 폴더의 원본 사이트

Accessing Resources Embedded in Another Assembly

다른 어셈블리에 내장 된 바이너리 리소스에 쉽게 액세스 할 수있는 기능은 매우 유용합니다 (주 실행 파일을 바꿀 필요없이 리소스를 업데이트 할 수있는 옵션이 더 많습니다).

/AssemblyReference;Component/ResourceName

여기서 AssemblyReference는 특정 어셈블리를 식별하지만 Component는 키워드이므로 문자 그대로 사용해야합니다. ResourceName은 하위 폴더를 포함 할 수있는 파일 이름입니다. AssemblyReference는 단순한 어셈블리 표시 이름이 될 수도 있고 선택적으로 .NET 어셈블리의 ID의 다른 부분을 포함 할 수도 있습니다.

버전 번호 및 공개 키 토큰 (강력한 이름의 어셈블리 인 경우). AssemblyReference에는 네 가지 옵션이 있습니다.

  • AssemblyName
  • AssemblyName; vVersionNumber (접두어가 필요한 v)
  • AssemblyName; PublicKeyToken
  • AssemblyName, vVersionNumber, PublicKeyToken

Accessing Resources at the Site of Origin

완전 신뢰 응용 프로그램은 느슨한 바이너리 자원에 대한 URL (Uniform Resource Locator) 또는 경로를 하드 코딩 할 수 있지만 원본 사이트를 이용하면 훨씬 유지하기 쉬운 방법입니다.(또한 부분 신뢰 응용 프로그램에 필요합니다.) 원본 사이트는 응용 프로그램 배포 방법에 따라 런타임에 다른 위치로 확인됩니다. Windows Installer와 함께 설치된 완전 신뢰 응용 프로그램의 경우 원본 사이트는 응용 프로그램의 루트 폴더입니다.
  • 완전 신뢰 ClickOnce 응용 프로그램의 경우 원본 사이트는 응용 프로그램이 배포 된 URL 또는 UNC 경로입니다.
  • 부분 신뢰 XAML 브라우저 응용 프로그램 (XBAP) 또는 ClickOnce 응용 프로그램의 경우 원본 사이트는 응용 프로그램을 호스팅하는 URL 또는 UNC 경로입니다.
  • 웹 브라우저에서 느슨한 XAML 페이지를 보려면 원본 사이트가 없습니다. 그것을 사용하려고 시도하면 예외가 발생합니다.

원본 사이트를 활용하는 구문은 다른 어셈블리에 포함 된 리소스를 참조하는 구문보다 더 낯설습니다. pack : // siteOfOrigin : ,,, / 접두어 다음에 리소스 이름 (하위 폴더를 포함 할 수 있음)을 사용해야합니다. siteOfOrigin은 다른 텍스트의 자리 표시자가 아니라 문자 그대로 사용되는 키워드입니다.

Logical Resources

두 번째 유형의 리소스는 WPF에서 처음 소개되고 WPF와 Silverlight에서 지원되는 메커니즘입니다.
이러한 논리적 리소스는 요소의 Resources 속성에 저장되고 (명명 된) 임의의 .NET 개체이며 일반적으로 여러 자식 요소가 공유해야합니다. FrameworkElement 및 FrameworkContentElement 기본 클래스는 모두 System.Windows.ResourceDictionary 유형의 Resources 속성을 가지므로 대부분의 WPF 클래스에는 이러한 속성이 있습니다. 이러한 논리적 리소스는 스타일 또는 데이터 공급자가 될 수 있습니다.

노란색 및 빨간색 브러시를 Window의 논리적 자원으로 구성하고이를 리소스 참조로 개별 요소에 적용 할 수 있습니다. 이것은 스타일 정보를 분리하고 통합하는 좋은 방법입니다. 논리적 자원 구성표에 의해 사용되는 개체를 공유하면 개체의 복잡성에 따라 훨씬 적은 메모리를 사용할 수 있습니다. 예제를 만들어 보겠습니다.

1:  <Window x:Class="Resources.MainWindow"  
2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
4:      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
5:      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
6:      xmlns:local="clr-namespace:Resources"  
7:      mc:Ignorable="d"  
8:      Title="MainWindow" Height="350" Width="525">  
9:    <Window.Resources>  
10:      <SolidColorBrush x:Key="backgroundBrush">Yellow</SolidColorBrush>  
11:      <SolidColorBrush x:Key="borderBrush">Red</SolidColorBrush>  
12:    </Window.Resources>  
13:    <Window.Background>  
14:      <StaticResource ResourceKey="backgroundBrush" />  
15:    </Window.Background>  
16:    <DockPanel>  
17:      <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Center" Height="50">  
18:        <Button Margin="5" BorderBrush="{StaticResource borderBrush}" Background="{StaticResource backgroundBrush}">Button 1</Button>  
19:        <Button Margin="5" BorderBrush="{StaticResource borderBrush}" Background="{StaticResource backgroundBrush}">Button 2</Button>  
20:        <Button Margin="5" BorderBrush="{StaticResource borderBrush}" Background="{StaticResource backgroundBrush}">Button 3</Button>  
21:        <Button Margin="5" BorderBrush="{StaticResource borderBrush}" Background="{StaticResource backgroundBrush}">Button 4</Button>  
22:      </StackPanel>  
23:      <ListBox />  
24:    </DockPanel>  
25:  </Window>  


요소에 리소스를 적용하려면 StaticResource 태그 확장 (System.Windows.StaticResourceExtension의 약자)을 사용합니다. 이 속성은 속성 요소 구문을 사용하여 Window.Background에 적용되고 속성 특성 구문을 사용하여 Button.Background 및 Button.BorderBrush에 적용됩니다. 이 예제의 두 리소스는 모두 브러시이기 때문에 브러시가 필요한 곳이면 어디에서나 적용 할 수 있습니다.

Resource Lookup 

StaticResource 태그 확장은 리소스 사전의 항목에 대한 키를 나타내는 단일 매개 변수를 허용합니다. 그러나 해당 항목은 현재 요소의 리소스 사전에있을 필요는 없습니다. 논리적 상위의 컬렉션이나 응용 프로그램 수준 또는 시스템 수준의 리소스 사전에 있을 수 있습니다.

 마크 업 확장 클래스는 논리적 트리를 탐색하여 항목을 찾을 수있는 기능을 구현합니다. 먼저 현재 요소의 Resources 컬렉션 (리소스 사전)을 확인합니다. 항목을 찾을 수 없으면 상위 요소, 상위 요소 등을 검사하여 루트 요소에 도달 할 때까지 검사합니다. 이 시점에서 Application 개체의 Resources 컬렉션을 확인합니다. 거기에 없으면 테마 자원의 집합을 검사합니다. 발견되지 않으면 시스템 정의 글꼴 (시스템 정의 글꼴, 색상 및 기타 설정 포함)을 최종 검사합니다. 항목이 이러한 컬렉션에 없으면 InvalidOperationException을 발생시킵니다.

이러한 동작 때문에 리소스는 일반적으로 공유 가능성을 최대한으로 높이기 위해 루트 요소의 리소스 사전이나 응용 프로그램 수준 사전에 저장됩니다. 각 개별 리소스 사전에 고유 키가 필요하지만 동일한 키를 여러 컬렉션에서 사용할 수 있습니다.

Static Versus Dynamic Resources

WPF는 논리 리소스에 액세스하는 두 가지 방법을 제공합니다. StaticResource를 정적으로 사용합니다. 즉, 리소스가 한 번만 적용됩니다 (처음 필요한 경우). DynamicResource와 동적으로 연결됩니다. 즉, 리소스가 변경 될 때마다 다시 적용됩니다.

Examining the Differences 

StaticResource와 DynamicResource의 주된 차이점은 리소스에 대한 모든 후속 업데이트가 DynamicResource를 사용하는 요소에만 반영된다는 것입니다. 이러한 업데이트는 자신의 코드에서 수행 할 수 있습니다 (예 : 노란색 브러시를 파란색으로 변경). 또는 사용자가 시스템 설정을 변경하여 수행 할 수 있습니다.

DynamicResource를 사용하면 여분의 추적 때문에 StaticResource보다 많은 오버 헤드가 필요합니다. 반면 DynamicResource를 사용하면로드 시간을 잠재적으로 향상시킬 수 있습니다. StaticResource 참조는 Window 또는 Page가로드 될 때 항상로드되지만 DynamicResource 참조는 실제로 사용될 때까지로드되지 않습니다. 또한 DynamicResource는 종속성 속성 값을 설정하는 데에만 사용할 수있는 반면 StaticResource는 어디서나 사용할 수 있습니다.

정적 리소스 액세스와 동적 리소스 액세스 간에는 하나의 차이가 있습니다. XAML에서 StaticResource를 사용하는 경우 전달 참조가 지원되지 않습니다. 즉, 리소스의 모든 용도는 XAML 파일에 선언 된 후에 나타나야합니다. 즉, 자원이 동일한 요소에 정의 된 경우 StaticResource를 속성 속성 구문과 함께 사용할 수 없습니다 (리소스가 반드시 나중에 표시되기 때문에)! DynamicResource에는이 제한이 없습니다.

Factoring XAML 

리소스는 페이지 내의 XAML을 분석하는 좋은 방법을 제공합니다. 응용 프로그램 수준 리소스로 저장하면 별도의 XAML 파일에 살 수 있습니다. 그러나 리소스 집합을 임의의 XAML 파일로 분할하려는 경우 (유지 관리 또는 유연성을 위해) 논리 트리에 저장되는 위치에 상관없이 ResourceDictionary 클래스의 MergedDictionaries 속성을 활용하여이를 달성 할 수 있습니다. 예를 들어 Window는 리소스 컬렉션을 다음과 같이 설정하여 여러 리소스 사전을 개별 파일에서 병합 할 수 있습니다.

1:  <Window.Resources>  
2:      <ResourceDictionary>  
3:        <ResourceDictionary.MergedDictionaries>  
4:          <ResourceDictionary Source="file1.xaml"/>  
5:          <ResourceDictionary Source="file2.xaml"/>  
6:        </ResourceDictionary.MergedDictionaries>  
7:      </ResourceDictionary>  
8:    </Window.Resources>  

별도의 파일은 ResourceDictionary를 루트 요소로 사용해야합니다. 예를 들어, file1.xaml은 다음을 포함 할 수 있습니다.

1:  <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  
2:    <Image x:Key="logo" Source="logo.jpg"/>  
3:  </ResourceDictionary>   

병합 된 사전에 중복 키가있는 경우 마지막 키가 하나씩 사용됩니다 (단일 사전에 중복 키가있는 경우와 달리).

Resources Without Sharing 

기본적으로 자원이 여러 위치에 적용되면 동일한 객체 인스턴스가 모든 곳에서 사용됩니다. 이것은 대개 원하는 동작입니다. 그러나 컴파일 된 리소스 사전의 항목을 x:Shared = "False"로 표시하여 해당 리소스에 대한 각 요청이 다른 리소스와 독립적으로 수정할 수있는 개체의 고유 한 인스턴스를 생성하도록 할 수 있습니다. 이 동작이 흥미로울 수있는 한 가지 경우는 전체 이미지 (또는 다른 Visual 파생 개체)를 리소스로 사용 할 때 입니다. 이러한 자원은 각 응용 프로그램이 동일한 인스턴스이기 때문에 요소 트리에서 한 번만 적용될 수 있습니다. 그러나 x:Shared = "False"로 설정하면이 동작이 변경되므로 리소스를 독립 개체로 여러 번 적용 할 수 있습니다. 이 작업은 다음과 같이 수행 할 수 있습니다.

1:  <Window x:Class="Resources.ResourcesWithoutSharing"  
2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
4:      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
5:      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
6:      xmlns:local="clr-namespace:Resources"  
7:      mc:Ignorable="d"  
8:      Title="ResourcesWithoutSharing" Height="300" Width="300">  
9:    <Window.Resources>  
10:      <Image x:Shared="False" x:Key="zoom" Height="21" Source="item_icon.PNG" />  
11:    </Window.Resources>  
12:    <StackPanel>  
13:      <StaticResource ResourceKey="zoom" />  
14:      <StaticResource ResourceKey="zoom" />  
15:      <StaticResource ResourceKey="zoom" />  
16:    </StackPanel>  
17:  </Window>  

x:Shared는 컴파일 된 XAML 파일에서만 사용할 수 있습니다. 느슨한 XAML 파일에서의 사용은 지원되지 않습니다.

Defining and Applying Resources in Procedural Code 

1:  window.Resources.Add(“backgroundBrush”, new SolidColorBrush(Colors.Yellow));  
2:  window.Resources.Add(“borderBrush”, new SolidColorBrush(Colors.Red));  

StaticResource의 경우 요소의 속성을 FindResource 메서드의 결과 (FrameworkElement 또는 FrameworkContentElement에서 상 속됨)로 설정하여 동일한 동작을 얻을 수 있습니다. 다음과 같은 XAML 코드는 C# 코드로 선언될 수 있습니다.

1:  <Button Background="{StaticResource backgroundBrush}" BorderBrush="{StaticResource borderBrush}"/>  

1:  Button button = new Button();  
2:  stackPanel.Children.Add(button);  
3:  button.Background = (Brush)button.FindResource(“backgroundBrush”);  
4:  button.BorderBrush = (Brush)button.FindResource(“borderBrush”);  

DynamicResource의 경우, 요소의 SetResourceReference (FrameworkElement 또는 FrameworkContentElement에서도 상속)에 대한 호출은 종속성 속성으로 업데이트 할 수있는 바인딩을 설정하는 트릭을 수행합니다.

1:  <Button Background="{DynamicResource backgroundBrush}" BorderBrush="{DynamicResource borderBrush}"/>  

1:  Button button = new Button();  
2:  button.SetResourceReference(Button.BackgroundProperty, “backgroundBrush”);  
3:  button.SetResourceReference(Button.BorderBrushProperty, “borderBrush”);  

FindResource 또는 TryFindResource에 대한 호출은 해당 키가있는 적절한 리소스 사전에 리소스를 추가하기 전에 호출하면 실패합니다. 반면에 SetResourceReference는 리소스가 추가되기 전에 호출 될 수 있습니다.







댓글

이 블로그의 인기 게시물

[C#] Task 완료 시 다른 Task를 자동으로 수행

[C#] 태스크(Task)가 완료될 때 까지 대기하여 결과를 얻는 방법

[C#] 명시적으로 Task 생성 및 실행