안녕하세요. 김대욱입니다. 이번시간에 소개해 드릴 내용은 임의로 제작한 Attribute를 UI에 Binding 하기 위한 MarkupExtension에 대해 소개해 드리겠습니다. 이 내용은 데브피아 WPF&Silverlight마을에서 이광현 (dololas)님께서 질문해주신 내용입니다. 간단하게 이번시간에 하고자 하는 내용을 그림으로 표현 하면 아래와 같습니다.
먼저 위 그림과 같이 Header부분에 제목, 감독, 출연배우라고 출력만 하면 되는 상황이라면 아래와 같이 직접 명시해줄 수 있을텐데요, 질문자 님께서 말씀 하신 내용은 명시적으로 Header값을 입력하지 않고, 지정한 Attribute에 따라 Header의 출력 내용을 결정 하고자 하셨으므로 이에 따른 해결 방법에 대해 알아보도록 하겠습니다.
- <GridViewColumn Width="80" Header="제목" DisplayMemberBinding="{Binding Title}" />
- <GridViewColumn Width="80" Header="감독" DisplayMemberBinding="{Binding Director}"/>
- <GridViewColumn Width="200" Header="출연 배우" DisplayMemberBinding="{Binding Actor}"/>
이번 예제에 사용되는 Class와 Attribute의 구조는 다음과 같습니다.
- public class DisplayName : Attribute
- {
- public string Value { get; set; }
- }
- public class Movie
- {
- [DisplayName(Value = "제목")]
- public string Title { get; set; }
- [DisplayName(Value = "감독")]
- public string Director { get; set; }
- [DisplayName(Value = "출연 배우")]
- public string Actor { get; set; }
- }
일단 위와 같은 상황에서 가장먼저 떠오르는게 DataBinding이 지만, DataBinding은 Property와 Property간의 연결을 제공하기 때문에 Attribute와는 함께 사용하실 수 없습니다. 따라서 Attribute 값을 반환 하는 MarkupExtension을 구현하여 해결해야 합니다. 아래는 MarkupExtension 구현 부분 소스코드입니다.
- [MarkupExtensionReturnType(typeof(string))]
- public class HeaderExtension : MarkupExtension
- {
- public string Path { get; set; }
- public Type Type { get; set; }
-
- public HeaderExtension() { }
- public HeaderExtension(string Path)
- : this()
- {
- this.Path = Path;
- }
-
- public override object ProvideValue(IServiceProvider serviceProvider)
- {
- MemberInfo Info = Type.GetMember(Path)[0];
- return (DisplayText.GetCustomAttribute(Info, typeof(DisplayText)) as DisplayText).Value;
- }
- }
MarkupExtension 파라미터로 입력받은 Type과 MemberPath정보를 기반으로, CustomAttribute의 값을 가져옵니다. 간단하죠? 실제 사용할때에는 아래와 같이 사용하시면 되겠습니다.
- <ListView>
- <ListView.View>
- <GridView>
- <GridViewColumn Width="80" Header="{m:Header Title, Type=m:Movie}" DisplayMemberBinding="{Binding Title}" />
- <GridViewColumn Width="80" Header="{m:Header Director, Type=m:Movie}" DisplayMemberBinding="{Binding Director}"/>
- <GridViewColumn Width="200" Header="{m:Header Actor, Type=m:Movie}" DisplayMemberBinding="{Binding Actor}"/>
- </GridView>
- </ListView.View>
- <m:Movie Title="국가대표" Director="김용화" Actor="하정우, 성동일, 김지석"/>
- <m:Movie Title="해운대" Director="윤제균" Actor="설경구, 하지원, 박중훈"/>
- <m:Movie Title="블랙" Director="산제이 릴라 " Actor="라니 무커르지, 아미타브 밧찬"/>
|