검색결과 리스트
글
화면에 노출되는 프로퍼티는?
머릿말
앞서 xaml 코드를 조금 살펴 보았습니다. 그런데 조금 특이한게 보이네요.
<TextBlock>Hello, World!</TextBlock>
위 코드와 아래 코드는 동일합니다.
<TextBlock Text="Hello, World!"></TextBlock>
어떻게 이게 가능할까요? Property 를 명시적으로 지정하지 않고, 그냥 Node 안에 값을 넣었는데, 자동으로 Text 프로퍼티에 값이 들어갑니다.
ContentProperty
비밀은 ContentProperty 안에 있습니다. msdn 에 찾아보면,
Indicates which property of a type is the XAML content property. A XAML processor uses this information when processing XAML child elements of XAML representations of the attributed type.
이렇게 설명이 되어 있습니다. XAML 프로세서가 XAML 의 자식 엘리먼트를 프로세싱할때 사용하는 정보라고 되어 있네요.
테스트를 위해서 코드를 만들어 보겠습니다.
테스트 코드
아래처럼 UserTextControl 이라는 UserControl 을 하나 만들었습니다.
public class UserTextControl : Control
{
static UserTextControl() {
DefaultStyleKeyProperty.OverrideMetadata(typeof(UserTextControl), new FrameworkPropertyMetadata(typeof(UserTextControl)));
}
public string Text {
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
// Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(UserTextControl), new PropertyMetadata(string.Empty));
}
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test">
<Style TargetType="{x:Type local:UserTextControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:UserTextControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter Content="{TemplateBinding Text}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
자동으로 생성된 UserTextControl 의 스타일에 ContentPresenter 를 추가해 주었습니다. 그리고 화면에 Text 가 바인딩되어 출력되도록 하였습니다.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:test="clr-namespace:Test"
x:Class="Test.MainWindow"
Title="MainWindow" Height="100" Width="200">
<Grid>
<test:UserTextControl Text="Hello, World"></test:UserTextControl>
</Grid>
</Window>
실행하면, 화면에 Hello,World 가 출력됩니다.
이제 이번 본론으로 돌아와서, 아래처럼 MainWindow 를 수정해 보도록 하겠습니다.
<test:UserTextControl>Hello, World</test:UserTextControl>
그대로 빌드하면 오류가 발생하네요. TextBlock 의 경우, 위와 같은 형태로 코드를 작성해도 알아서 Text 라는 프로퍼티로 값이 설정되었는데.... 의도한대로 동작하지 않습니다. ContentProperty 를 설정해 보도록 하죠.
[ContentProperty("Text")]
public class UserTextControl : Control
{
// 생략...
매우 간단합니다. class 선언부분에 ContentProperty 라는 Attribute 를 추가해 주면 됩니다. 파라미터는 프로퍼티 이름을 넣어주면 됩니다. 다시 빌드해서 실행해 보면, 잘 동작하는 것을 확인 하실 수 있습니다.
추가 테스트 코드
이번엔 조금 변형하여, 아래 코드가 동작하도록 해 봅시다.
<test:UserTextControl>
<system:String>Hello, World #1</system:String>
<system:String>Hello, World #2</system:String>
<system:String>Hello, World #3</system:String>
</test:UserTextControl>
화면에 리스트 형태가 출력되도록 먼저 스타일을 수정하도록 하겠습니다.
<Style TargetType="{x:Type local:UserTextControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:UserTextControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ListBox ItemsSource="{TemplateBinding Lines}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
그리고 난 뒤, 아래처럼 UserTextControl.cs 를 수정해 주면 됩니다.
[ContentProperty("Lines")]
public class UserTextControl : Control
{
static UserTextControl() {
DefaultStyleKeyProperty.OverrideMetadata(typeof(UserTextControl), new FrameworkPropertyMetadata(typeof(UserTextControl)));
}
public ObservableCollection<string> Lines {
get { return (ObservableCollection<string>)GetValue(LinesProperty); }
set { SetValue(LinesProperty, value); }
}
public static readonly DependencyProperty LinesProperty =
DependencyProperty.Register("Lines", typeof(ObservableCollection<string>), typeof(UserTextControl), new PropertyMetadata(new ObservableCollection<string>()));
}
요컨데, ContentProperty 가 없었다면, 아래처럼 작성해야 했을 것입니다 :)
<test:UserTextControl>
<test:UserTextControl.Lines>
<system:String>Hello, World #1</system:String>
<system:String>Hello, World #2</system:String>
<system:String>Hello, World #3</system:String>
</test:UserTextControl.Lines>
</test:UserTextControl>
'Microsoft > WPF' 카테고리의 다른 글
TreeView Template 을 통한 Canvas 만들기 (1) | 2014.11.12 |
---|---|
MEF(Managed Extensibility Framework) (2) | 2014.05.19 |
TypeConverter (0) | 2014.05.12 |
XAML 의 문법구조 (0) | 2014.05.12 |
xaml 과 cs 파일의 관계 (1) | 2014.05.08 |
RECENT COMMENT