내용 보기

작성자

관리자 (IP : 172.17.0.1)

날짜

2020-07-10 03:14

제목

[WPF] ListView Column Header값을 어트리뷰트의 설정 값으로 설정하기. [Custom Attribute MarkupExtenstion]


안녕하세요. 김대욱입니다. 이번시간에 소개해 드릴 내용은 임의로 제작한 Attribute를 UI에 Binding 하기 위한 MarkupExtension에 대해 소개해 드리겠습니다. 이 내용은 데브피아 WPF&Silverlight마을에서 이광현 (dololas)님께서 질문해주신 내용입니다. 간단하게 이번시간에 하고자 하는 내용을 그림으로 표현 하면 아래와 같습니다.


먼저 위 그림과 같이 Header부분에 제목, 감독, 출연배우라고 출력만 하면 되는 상황이라면 아래와 같이 직접 명시해줄 수 있을텐데요, 질문자 님께서 말씀 하신 내용은 명시적으로 Header값을 입력하지 않고, 지정한 Attribute에 따라  Header의 출력 내용을 결정 하고자 하셨으므로 이에 따른 해결 방법에 대해 알아보도록 하겠습니다.


  1. <GridViewColumn Width="80" Header="제목" DisplayMemberBinding="{Binding Title}" />  
  2. <GridViewColumn Width="80" Header="감독" DisplayMemberBinding="{Binding Director}"/>  
  3. <GridViewColumn Width="200" Header="출연 배우" DisplayMemberBinding="{Binding Actor}"/>  

이번 예제에 사용되는 Class와 Attribute의 구조는 다음과 같습니다.

  1. public class DisplayName : Attribute  
  2. {  
  3.     public string Value { getset; }  
  4. }  
  5. public class Movie  
  6. {  
  7.     [DisplayName(Value = "제목")]  
  8.     public string Title { getset; }  
  9.     [DisplayName(Value = "감독")]  
  10.     public string Director { getset; }  
  11.     [DisplayName(Value = "출연 배우")]  
  12.     public string Actor { getset; }  
  13. }  


일단 위와 같은 상황에서 가장먼저 떠오르는게 DataBinding이 지만, DataBinding은 Property와 Property간의 연결을 제공하기 때문에 Attribute와는 함께 사용하실 수 없습니다. 따라서 Attribute 값을 반환 하는 MarkupExtension을 구현하여 해결해야 합니다. 아래는 MarkupExtension 구현 부분 소스코드입니다.

  1. [MarkupExtensionReturnType(typeof(string))]  
  2. public class HeaderExtension : MarkupExtension  
  3. {  
  4.     public string Path { getset; }  
  5.     public Type Type { getset; }  
  6.   
  7.     public HeaderExtension() { }  
  8.     public HeaderExtension(string Path)  
  9.         : this()  
  10.     {  
  11.         this.Path = Path;  
  12.     }  
  13.   
  14.     public override object ProvideValue(IServiceProvider serviceProvider)  
  15.     {  
  16.         MemberInfo Info = Type.GetMember(Path)[0];  
  17.         return (DisplayText.GetCustomAttribute(Info, typeof(DisplayText)) as DisplayText).Value;  
  18.     }  
  19. }  


MarkupExtension 파라미터로 입력받은 Type과 MemberPath정보를 기반으로, CustomAttribute의 값을 가져옵니다. 간단하죠? 실제 사용할때에는 아래와 같이 사용하시면 되겠습니다.


  1. <ListView>  
  2.     <ListView.View>  
  3.         <GridView>  
  4.             <GridViewColumn Width="80" Header="{m:Header Title, Type=m:Movie}" DisplayMemberBinding="{Binding Title}" />  
  5.             <GridViewColumn Width="80" Header="{m:Header Director, Type=m:Movie}" DisplayMemberBinding="{Binding Director}"/>  
  6.             <GridViewColumn Width="200" Header="{m:Header Actor, Type=m:Movie}" DisplayMemberBinding="{Binding Actor}"/>  
  7.         </GridView>  
  8.     </ListView.View>  
  9.     <m:Movie Title="국가대표" Director="김용화" Actor="하정우, 성동일, 김지석"/>  
  10.     <m:Movie Title="해운대" Director="윤제균" Actor="설경구, 하지원, 박중훈"/>  
  11.     <m:Movie Title="블랙" Director="산제이 릴라 " Actor="라니 무커르지, 아미타브 밧찬"/>  


출처1

http://wpfkorea.tistory.com/170

출처2