종속성 속성 개요(WPF .NET)

WPF(Windows Presentation Foundation)에서는 형식의 속성 기능을 확장하는 데 사용할 수 있는 서비스 집합을 제공합니다. 해당 서비스를 ‘WPF 속성 시스템’이라고 통칭합니다. WPF 속성 시스템에서 지원하는 속성을 종속성 속성이라고 합니다. 이 개요에서는 XAML 및 코드에서 기존 종속성 속성을 사용하는 방법을 포함하여 WPF 속성 시스템 및 종속성 속성의 기능에 대해 설명합니다. 또한 이 개요에서는 종속성 속성 메타데이터 같은 종속성 속성의 특수한 측면과 사용자 지정 클래스에서 종속성 속성을 직접 만드는 방법을 소개합니다.

중요

.NET 7 및 .NET 6에 관한 데스크톱 가이드 설명서는 제작 중입니다.

필수 구성 요소

이 문서에서는 .NET 형식 시스템 및 개체 지향 프로그래밍에 관한 기본 지식이 있다고 가정합니다. 이 문서의 예제를 따르려면 XAML을 이해하고 WPF 애플리케이션을 작성하는 방법을 알면 도움이 됩니다. 자세한 내용은 자습서: .NET을 사용하여 새 WPF 앱 만들기를 참조하세요.

종속성 속성 및 CLR 속성

WPF 속성은 일반적으로 표준 .NET 속성으로 노출됩니다. 이러한 속성을 기본 수준에서 조작할 수 있으며 종속성 속성으로 구현되는지는 알 수 없습니다. 그러나 WPF 속성 시스템의 일부 또는 전부에 대해 잘 알고 있으면 이러한 기능을 활용하는 데 도움이 됩니다.

종속성 속성의 용도는 다음과 같은 다른 입력 값을 기반으로 속성의 값을 계산하는 방법을 제공하는 것입니다.

  • 테마 및 사용자 기본 설정과 같은 시스템 속성.
  • 데이터 바인딩 및 애니메이션/스토리보드와 같은 Just-In-Time 속성 결정 메커니즘.
  • 리소스 및 스타일과 같은 다용도 템플릿.
  • 요소 트리의 다른 요소와 부모-자식 관계를 맺음으로써 알게 된 값.

또한 종속성 속성은 다음을 제공할 수 있습니다.

  • 자체 포함 유효성 검사.
  • 기본값.
  • 다른 속성의 변경 내용을 모니터링하는 콜백.
  • 런타임 정보를 기반으로 속성 값을 강제 변환할 수 있는 시스템.

파생 클래스는 기존 속성의 실제 구현을 재정의하거나 새 속성을 만드는 대신 종속성 속성의 메타데이터를 재정의하여 기존 속성의 특정 특성을 변경할 수도 있습니다.

SDK 참조에서는 속성에 대한 관리되는 참조 페이지에 종속성 속성 정보 섹션이 있는지 여부에 따라 종속성 속성을 식별할 수 있습니다. 종속성 속성 정보 섹션에는 해당 종속성 속성의 DependencyProperty 식별자 필드에 대한 링크가 포함되어 있습니다. 또한 해당 속성에 대한 메타데이터 옵션 목록, 클래스별 재정의 정보 및 기타 세부 정보도 포함됩니다.

종속성 속성의 CLR 속성 지원

종속성 속성 및 WPF 속성 시스템은 private 필드로 속성을 지원하는 표준 패턴에 대한 대안으로 속성을 지원하는 형식을 제공하여 속성 기능을 확장합니다. 이 형식의 이름은 DependencyProperty입니다. WPF 속성 시스템을 정의하는 다른 중요한 형식은 종속성 속성을 등록하고 소유할 수 있는 기본 클래스를 정의하는 DependencyObject입니다.

다음은 몇 가지 일반적으로 사용되는 용어입니다.

  • 종속성 속성: DependencyProperty에 의해 지원되는 속성입니다.

  • 종속성 속성 식별자: 종속성 속성을 등록할 때 반환 값으로 가져온 다음, 클래스의 정적 멤버로 저장하는 DependencyProperty 인스턴스입니다. WPF 속성 시스템과 상호 작용하는 많은 API는 종속성 속성 식별자를 매개 변수로 사용합니다.

  • CLR "래퍼": 속성의 getset 구현입니다. 이러한 구현은 GetValueSetValue 호출에서 종속성 속성 식별자를 사용하여 통합합니다. 이러한 방식으로 WPF 속성 시스템은 속성에 대한 지원을 제공합니다.

다음 예제에서는 IsSpinning 종속성 속성을 정의하여 DependencyProperty 식별자와 이 식별자가 지원하는 속성의 관계를 보여 줍니다.

public static readonly DependencyProperty IsSpinningProperty = DependencyProperty.Register(
    "IsSpinning", typeof(bool),
    typeof(MainWindow)
    );

public bool IsSpinning
{
    get => (bool)GetValue(IsSpinningProperty);
    set => SetValue(IsSpinningProperty, value);
}
Public Shared ReadOnly IsSpinningProperty As DependencyProperty =
    DependencyProperty.Register("IsSpinning", GetType(Boolean), GetType(MainWindow))

Public Property IsSpinning As Boolean
    Get
        Return GetValue(IsSpinningProperty)
    End Get
    Set(value As Boolean)
        SetValue(IsSpinningProperty, value)
    End Set
End Property

속성과 해당 지원 DependencyProperty 필드의 명명 규칙은 중요합니다. 필드의 이름은 항상 접미사 Property가 추가된 속성의 이름입니다. 이 규칙과 그 이유에 대한 자세한 내용은 사용자 지정 종속성 속성을 참조하세요.

속성 값 설정

속성은 코드 또는 XAML에서 설정할 수 있습니다.

XAML에서 속성 값 설정

다음 XAML 예제에서는 단추의 배경색을 빨간색으로 지정합니다. XAML 특성의 문자열 값은 WPF XAML 파서에 의해 WPF 형식으로 형식 변환됩니다. 생성된 코드에서 WPF 형식은 SolidColorBrush를 통해 Color입니다.

<Button Content="I am red" Background="Red"/>

XAML은 속성을 설정하는 여러 구문 형식을 지원합니다. 특정 속성에 사용할 구문은 속성에서 사용하는 값 형식과 형식 변환기 존재와 같은 다른 요소에 따라 달라집니다. 속성 설정을 위한 XAML 구문에 대한 자세한 내용은 WPF의 XAMLXAML 구문 정보를 참조하세요.

다음 XAML 예제에서는 특성 구문 대신 속성 요소 구문을 사용하는 다른 단추 배경을 보여 줍니다. XAML은 단순한 단색을 설정하는 대신 단추 Background 속성을 이미지로 설정합니다. 요소는 해당 이미지를 나타내고 중첩된 요소의 특성은 이미지의 원본을 지정합니다.

<Button Content="I have an image background">
    <Button.Background>
        <ImageBrush ImageSource="stripes.jpg"/>
    </Button.Background>
</Button>

코드에서 속성 설정

코드에서 종속성 속성 값을 설정하려면 일반적으로 CLR “래퍼”에 의해 노출되는 set 구현을 호출하면 됩니다.

Button myButton = new();
myButton.Width = 200.0;
Dim myButton As New Button With {
    .Width = 200.0
}

속성 값을 가져오려면 기본적으로 get "래퍼" 구현을 호출합니다.

double whatWidth = myButton.Width;
Dim whatWidth As Double = myButton.Width

속성 시스템 API GetValueSetValue를 직접 호출할 수도 있습니다. API를 직접 호출하는 것은 일부 시나리오에는 적합하지만 일반적으로 기존 속성을 사용하는 경우에는 그렇지 않습니다. 일반적으로 래퍼가 더 편리하고 개발자 도구에서 속성을 더 잘 노출합니다.

또한 속성은 XAML에서 설정한 다음 나중에 코드 숨김을 통해 코드에서 액세스할 수 있습니다. 자세한 내용은 WPF의 코드 숨김 및 XAML을 참조하세요.

종속성 속성에서 제공하는 속성 기능

필드에 의해 지원되는 속성과 달리 종속성 속성은 속성의 기능을 확장합니다. 추가된 기능은 다음 기능 중 하나를 나타내거나 지원하는 경우가 많습니다.

리소스

종속성 속성 값은 리소스를 참조하여 설정할 수 있습니다. 일반적으로 리소스는 페이지 루트 요소 또는 애플리케이션의 Resources 속성 값으로 지정됩니다. 이러한 위치를 통해 리소스에 가장 편리하게 액세스할 수 있기 때문입니다. 이 예제에서는 SolidColorBrush 리소스를 정의합니다.

<StackPanel.Resources>
    <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
</StackPanel.Resources>

이제 리소스가 정의되었으므로 리소스를 참조하여 Background 속성의 값을 제공할 수 있습니다.

<Button Background="{DynamicResource MyBrush}" Content="I am gold" />

WPF XAML에서 정적 또는 동적 리소스 참조를 사용할 수 있습니다. 이 특정 리소스는 DynamicResource로 참조됩니다. 동적 리소스 참조는 종속성 속성을 설정하는 데만 사용할 수 있으므로 특히 WPF 속성 시스템에서 사용하도록 설정된 동적 리소스 참조 사용입니다. 자세한 내용은 XAML 리소스를 참조하세요.

참고

리소스는 로컬 값으로 처리되며, 다른 로컬 값을 설정하면 리소스 참조가 제거됩니다. 자세한 내용은 종속성 속성 값 우선 순위를 참조하세요.

데이터 바인딩

종속성 속성은 데이터 바인딩을 통해 값을 참조할 수 있습니다. 데이터 바인딩은 XAML의 특정 태그 확장 구문이나 코드의 Binding 개체를 통해 작동합니다. 데이터 바인딩을 사용하면 데이터 원본에서 값을 가져오는 시간인 런타임까지 최종 속성 값 결정이 지연됩니다.

다음 예에서는 XAML에서 선언된 바인딩을 사용하여 Button에 대한 Content 속성을 설정합니다. 바인딩은 상속된 데이터 컨텍스트 및 XmlDataProvider 데이터 원본(표시되지 않음)을 사용합니다. 바인딩 자체는 데이터 원본 내에서 XPath로 원하는 원본 속성을 지정합니다.

<Button Content="{Binding Source={StaticResource TestData}, XPath=test[1]/@text}"/>

참고

바인딩은 로컬 값으로 처리되며, 다른 로컬 값을 설정하면 바인딩이 제거됩니다. 자세한 내용은 종속성 속성 값 우선 순위를 참조하세요.

종속성 속성, 즉 DependencyObject 클래스는 데이터 바인딩 작업에 대한 DependencyObject 원본 속성 값의 변경 내용을 알리기 위한 INotifyPropertyChanged를 기본적으로 지원하지 않습니다. 데이터 바인딩 대상의 변경 내용을 보고할 수 있도록 데이터 바인딩에서 사용할 속성을 만드는 방법에 대한 자세한 내용은 데이터 바인딩 개요를 참조하세요.

스타일

스타일 및 템플릿은 종속성 속성을 사용하는 주요 이유입니다. 스타일은 애플리케이션 UI를 정의하는 속성을 설정하는 데 특히 유용합니다. 스타일은 일반적으로 XAML의 리소스로 정의됩니다. 일반적으로 스타일은 특정 속성에 대한 "setter"와 또 다른 속성에 대한 실시간 값에 따라 속성 값을 변경하는 "트리거"를 포함하기 때문에 속성 시스템과 상호 작용합니다.

다음 예제에서는 Resources 사전(표시되지 않음) 내에 정의되는 간단한 스타일을 만듭니다. 그런 다음 해당 스타일이 ButtonStyle 속성에 직접 적용됩니다. 스타일 내의 setter는 스타일이 적용된 Button에 대한 Background 속성을 녹색으로 설정합니다.

<Style x:Key="GreenButtonStyle">
    <Setter Property="Control.Background" Value="Green"/>
</Style>
<Button Style="{StaticResource GreenButtonStyle}" Content="I am green"/>

자세한 내용은 스타일 지정 및 템플릿을 참조하세요.

애니메이션

종속성 속성에 애니메이션을 적용할 수 있습니다. 적용된 애니메이션이 실행되면 애니메이션 값이 로컬 값을 비롯한 다른 속성 값보다 우선 순위가 높습니다.

다음 예제에서는 ButtonBackground 속성에 애니메이션 효과를 적용합니다. 기술적으로 속성 요소 구문은 빈 SolidColorBrushBackground로 설정하고 SolidColorBrushColor 속성에 애니메이션 효과를 적용합니다.

<Button Content="I am animated">
    <Button.Background>
        <SolidColorBrush x:Name="AnimBrush"/>
    </Button.Background>
    <Button.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimation
                        Storyboard.TargetName="AnimBrush" 
                        Storyboard.TargetProperty="(SolidColorBrush.Color)"
                        From="Blue" To="White" Duration="0:0:1" 
                        AutoReverse="True" RepeatBehavior="Forever" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

속성에 애니메이션 효과를 적용하는 방법에 대한 자세한 내용은 애니메이션 개요스토리보드 개요를 참조하세요.

메타데이터 재정의

원래 종속성 속성을 등록한 클래스에서 파생시킬 때 해당 메타데이터를 재정의하여 종속성 속성의 특정 동작을 변경할 수 있습니다. 메타데이터 재정의는 DependencyProperty 식별자를 사용하며 속성을 다시 구현할 필요가 없습니다. 메타데이터 변경은 속성 시스템에서 기본적으로 처리됩니다. 각 클래스는 잠재적으로 형식별로 기본 클래스에서 상속되는 모든 속성에 대해 개별 메타데이터를 보유합니다.

다음 예제에서는 DefaultStyleKey 종속성 속성의 메타데이터를 재정의합니다. 이 특정 종속성 속성에 대한 메타데이터 재정의는 테마에서 기본 스타일을 사용할 수 있는 컨트롤을 만드는 구현 패턴의 일부입니다.

public class SpinnerControl : ItemsControl
{
    static SpinnerControl() => DefaultStyleKeyProperty.OverrideMetadata(
            typeof(SpinnerControl),
            new FrameworkPropertyMetadata(typeof(SpinnerControl))
        );
}
Public Class SpinnerControl
    Inherits ItemsControl
    Shared Sub New()
        DefaultStyleKeyProperty.OverrideMetadata(GetType(SpinnerControl), New FrameworkPropertyMetadata(GetType(SpinnerControl)))
    End Sub
End Class

종속성 속성의 메타데이터를 재정의 또는 액세스하는 방법에 대한 자세한 내용은 종속성 속성의 메타데이터 재정의를 참조하세요.

속성 값 상속

요소는 개체 트리의 부모에서 종속성 속성의 값을 상속할 수 있습니다.

참고

속성 값 상속 동작은 모든 종속성 속성에 전역으로 사용되지는 않는데 상속에 대한 계산 시간이 성능에 영향을 주기 때문입니다. 속성 값 상속은 일반적으로 적용 가능성을 제안하는 시나리오에서만 사용하도록 설정됩니다. 종속성 속성이 상속되는지 여부는 SDK 참조에서 해당 종속성 속성에 대한 종속성 속성 정보 섹션을 통해 확인할 수 있습니다.

다음 예제에서는 바인딩의 소스를 지정하는 DataContext 속성이 포함된 바인딩을 보여 줍니다. 그러므로 자식 개체의 바인딩은 소스를 지정할 필요가 없으며, 부모 StackPanel 개체의 DataContext에서 상속된 값을 사용할 수 있습니다. 또는 자식 개체는 자체 DataContext 또는 BindingSource를 직접 지정할 수 있으며 상속된 값을 사용할 수 없습니다.

<StackPanel Canvas.Top="50" DataContext="{Binding Source={StaticResource TestData}}">
    <Button Content="{Binding XPath=test[2]/@text}"/>
</StackPanel>

자세한 내용은 속성 값 상속을 참조하세요.

WPF Designer 통합

종속성 속성으로 구현된 속성을 사용하는 사용자 지정 컨트롤은 Visual Studio용 WPF Designer와 잘 통합됩니다. 한 가지 예는 속성 창에서 직접 및 연결된 종속성 속성을 편집하는 기능입니다. 자세한 내용은 컨트롤 작성 개요를 참조하세요

종속성 속성 값 우선 순위

WPF 속성 시스템 내의 속성 기반 입력은 종속성 속성의 값을 설정할 수 있습니다. 종속성 속성 값 우선 순위는 속성이 해당 값을 가져오는 방법에 대한 다양한 시나리오가 예측 가능한 방식으로 상호 작용하도록 존재합니다.

참고

SDK 설명서에서 종속성 속성에 대해 설명할 때 "로컬 값" 또는 "로컬로 설정된 값"이라는 용어를 사용할 때가 가끔 있습니다. 로컬로 설정된 값은 코드의 개체 인스턴스에서 직접 설정되거나 XAML의 요소 특성으로 설정되는 속성 값입니다.

다음 예제에는 모든 단추의 Background 속성에 적용되지만 로컬로 설정된 Background 속성으로 하나의 단추를 지정하는 스타일이 포함되어 있습니다. 기술적으로 이 단추의 Background 속성은 두 번 설정되지만, 우선 순위가 가장 높은 값 하나만 적용됩니다. 로컬로 설정된 값은 여기에 존재하지 않는 실행 중인 애니메이션을 제외하고 우선 순위가 가장 높습니다. 따라서 두 번째 버튼은 스타일 setter 값 대신 Background 속성에 로컬로 설정된 값을 사용합니다. 첫 번째 버튼은 로컬 값이 없거나 스타일 setter보다 우선 순위가 높은 다른 값이 없으므로 Background 속성에 스타일 setter 값을 사용합니다.

<StackPanel>
    <StackPanel.Resources>
        <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
            <Setter Property="Background" Value="Orange"/>
        </Style>
    </StackPanel.Resources>
    <Button>I am styled orange</Button>
    <Button Background="Pink">I am locally set to pink (not styled orange)</Button>
</StackPanel>

종속성 속성 우선 순위의 존재 이유

로컬로 설정된 값은 요소 속성의 로컬 제어를 지원하는 스타일 setter 값보다 우선합니다. 자세한 내용은 종속성 속성 값 우선 순위를 참조하세요.

참고

WPF 요소에 정의된 속성 중 다수는 종속성 속성이 아닙니다. 종속성 속성은 일반적으로 WPF 속성 시스템의 기능이 필요한 경우에만 구현되었기 때문입니다. 기능에는 데이터 바인딩, 스타일 지정, 애니메이션, 기본값 지원, 상속, 연결된 속성 및 무효화가 포함됩니다.

종속성 속성에 대해 자세히 알아보기

  • 구성 요소 개발자 또는 애플리케이션 개발자는 데이터 바인딩 또는 스타일 지원이나 무효화 및 값 강제 변환 같은 기능을 추가하기 위해 종속성 속성을 직접 만들려고 할 수 있습니다. 자세한 내용은 사용자 지정 종속성 속성을 참조하세요.

  • 종속성 속성은 인스턴스에 액세스할 수 있는 모든 호출자가 액세스할 수 있거나 검색할 수 있는 공용 속성으로 간주하세요. 자세한 내용은 종속성 속성 보안을 참조하세요.

  • 연결된 속성은 XAML에서 특수한 구문을 지원하는 속성의 형식입니다. 연결된 속성은 종종 공용 언어 런타임 속성과 1:1 대응 관계가 없으며 반드시 종속성 속성인 것은 아닙니다. 연결된 속성의 기본 용도는 부모 요소와 자식 요소가 클래스 멤버 목록의 일부로 해당 속성을 포함하지 않는 경우에도 자식 요소가 부모 요소에 속성 값을 보고할 수 있도록 허용하는 것입니다. 한 가지 기본 시나리오는 자식 요소가 부모 요소에 자신을 UI에 표시하는 방법을 알릴 수 있도록 하는 것입니다. 예제를 보려면 DockLeft를 참조하세요. 자세한 내용은 연결된 속성 개요를 참조하세요.

참고 항목