[WPF] 의존 속성(Dependency Property)

이번 포스팅에서는 WPF(Windows Presentation Foundation)의 핵심 기능 중 하나인 의존 프로퍼티(Dependency Property)에 대해서 정리하겠습니다.

의존 속성(Dependency Property)란 무엇일까?

의존 속성(Dependency Property)는 WPF에서 UI 요소의 속성을 정의하고 관리하는 메커니즘으로 일반적인 속성과 다르게, 값의 변경을 추적하고, 데이터 바인딩(Data Binding), 스타일링, 애니메이션 등 다양한 기능을 지원합니다.

Dependency Property의 사용 이유

의존 속성(Dependency Property)를 사용하면 UI 요소간에 데이터를 쉽게 연결하고 공유할 수 있습니다. 이로 인해 개발자는 코드에서 직접 속성을 변경 관리하지 않아도 되며, 데이터의 일관성과 효율성을 유지할 수 있습니다.


Dependency Property 사용 방법

Dependency Property 정의

public static readonly DependencyProperty sampleDataProperty = DependencyProperty.Register(
            "sampleData", // (1)
            typeof(string), // (2)
            typeof(MainWindow), // (3)
            new FrameworkPropertyMetadata(
                null,  // (4)
                new PropertyChangedCallback(SampleDataPropertyChanged)  // (5)
                ) 
            );
  • (1) DependencyProperty로 등록할 Wrapper 속성 이름
  • (2) DependencyProperty 속성 타입
  • (3) DependencyProperty가 속해있는 ownerType
  • (4) 속성의 초기값
  • (5) 속성이 변경될 때 호출할 callback method
       * (4), (5)을 정의한 PropertyMetadata는 선택 사항

 

Dependency Property로 사용할 속성

public string sampleData
        {
            get { return (string)GetValue(sampleDataProperty); }
            set { SetValue(sampleDataProperty, value); }
        }
  •   GetValue, SetValue에 의존 속성(Dependency Property) 연결


Dependency Property의 callback method 정의

private static void SampleDataPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        { 
            // callback 내용 정의
        }

 

Dependency Property 예제

<Window x:Class="WPFExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFExample"
        mc:Ignorable="d"
        Title="MainWindow" Height="100" Width="220">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <RadioButton Content="고양이" GroupName="Animal" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="0" Checked="RadioButton_Checked"/>
        <RadioButton Content="강아지" GroupName="Animal" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="1" Checked="RadioButton_Checked"/>
        <RadioButton Content="토끼" GroupName="Animal" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="2" Checked="RadioButton_Checked"/>

        <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3">
            <Label Content="Old : "/>
            <Label x:Name="oldSelect" Width="60"/>
            <Label Content="New : "/>
            <Label x:Name="newSelect" Width="60"/>
            
        </StackPanel>

    </Grid>
</Window>

using System;
using System.Windows;
using System.Windows.Controls;

namespace WPFExample
{
    public partial class MainWindow : Window
    {
        public string Animal
        {
            get { return (string)GetValue(textProperty); }
            set { SetValue(textProperty, value); }
        }

        public static readonly DependencyProperty textProperty = DependencyProperty.Register(
            "Animal", // DependencyProperty로 등록할 Wrapper 속성 이름
            typeof(string), // DependencyProperty 속성 타입
            typeof(MainWindow), // DependencyProperty가 속해있는 ownerType
            new FrameworkPropertyMetadata(string.Empty, new PropertyChangedCallback(OnPropertyChanged))
            ); // FrameworkPropertyMetadata(속성의 초기값, 속성이 변경 될때 호출할 callback method)

        private static void OnPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            MainWindow window = (MainWindow)obj;
            if(e.OldValue != null && e.OldValue != string.Empty)
                window.oldSelect.Content = e.OldValue.ToString();
            window.newSelect.Content = e.NewValue.ToString();
            
        }

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
        }

        private void RadioButton_Checked(object sender, RoutedEventArgs e)
        {
            RadioButton radioButton = (RadioButton)sender;
            Animal = radioButton.Content.ToString();
        }
    }
}


동물 이름 RadioButton을 누르게 되면 선택한 Button의 Content 정보가 Animal 객체에 반영되고 Callback 함수(OnPropertyChanged)에 정의된 내용대로 oldSelect(Label), newSelect(Label)에 입력됩니다.


DependencyProperty
DependencyProperty

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다