■ 의존 속성(DependencyProperty)란?
Property 값이 변경되었을 때, 자동으로 어떤 작업을 처리해 주는 것
스타일 지정, 데이터 바인딩, 애니메이션 처리 등에 사용됩니다.
■ DependencyProperty 사용 방법
- DependencyProperty 정의
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는 선택 사항
- DependencyProperty로 사용할 속성
public string sampleData
{
get { return (string)GetValue(sampleDataProperty); }
set { SetValue(sampleDataProperty, value); }
}
· GetValue, SetValue로 DependencyProperty 연결
- DependencyProperty에 사용될 callback method 정의
private static void SampleDataPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
// callback 내용 정의
}
■ DependencyProperty Example
- Example 설명
· 색상(radiobutton), 적용할 영역(checkbox)를 선택 후 적용(button) 버튼 클릭
· 선택한 색상과 영역 정보를 DependencyProperty로 정의한 selectColor, checkStatus 값에 할당
· selectColor, checkStatus의 값이 변경될 때마다 callback method 호출
· callback method에 정의된 '적용 버튼' 하단의 line 박스 색상 변경 및 이전 상태 표기
- MainWindow.xaml
<Window x:Class="DependencyPropertyEx.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:DependencyPropertyEx"
mc:Ignorable="d"
Title="MainWindow" Height="400" Width="400">
<StackPanel VerticalAlignment="Center">
<StackPanel x:Name="radioGroup" Orientation="Horizontal"
HorizontalAlignment="Center" VerticalAlignment="Center">
<RadioButton GroupName="colorGroup" Content="Red" Margin="5,5,5,5"/>
<RadioButton GroupName="colorGroup" Content="Blue" Margin="5,5,5,5"/>
<RadioButton GroupName="colorGroup" Content="Yellow" Margin="5,5,5,5"/>
<RadioButton GroupName="colorGroup" Content="Green" Margin="5,5,5,5"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"
VerticalAlignment="Center">
<CheckBox x:Name="chk_01" Content="Line_01" Margin="5,5,5,5"/>
<CheckBox x:Name="chk_02" Content="Line_02" Margin="5,5,5,5"/>
<CheckBox x:Name="chk_03" Content="Line_03" Margin="5,5,5,5"/>
<CheckBox x:Name="chk_04" Content="Line_04" Margin="5,5,5,5"/>
</StackPanel>
<Button Content="적용" Click="Button_Click" Margin="5,5,5,5"/>
<Grid x:Name="SelectedColorGrid" Margin="5,0,5,0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Border x:Name="br_01" BorderBrush="Gray" BorderThickness="1"
Grid.Row="0" Grid.Column="0" Margin="1,0,1,0">
<Label Content="Line_01" VerticalContentAlignment="Center"
HorizontalContentAlignment="Center" Height="200"/>
</Border>
<Border x:Name="br_02" BorderBrush="Gray" BorderThickness="1"
Grid.Row="0" Grid.Column="1" Margin="1,0,1,0">
<Label Content="Line_02" VerticalContentAlignment="Center"
HorizontalContentAlignment="Center" Height="200"/>
</Border>
<Border x:Name="br_03" BorderBrush="Gray" BorderThickness="1"
Grid.Row="0" Grid.Column="2" Margin="1,0,1,0">
<Label Content="Line_03" VerticalContentAlignment="Center"
HorizontalContentAlignment="Center" Height="200"/>
</Border>
<Border x:Name="br_04" BorderBrush="Gray" BorderThickness="1"
Grid.Row="0" Grid.Column="3" Margin="1,0,1,0">
<Label Content="Line_04" VerticalContentAlignment="Center"
HorizontalContentAlignment="Center" Height="200"/>
</Border>
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"
VerticalAlignment="Center" Margin="5,5,5,5">
<Label Content="이전 색상 : "/>
<Label x:Name="oldColor"/>
<Label Content=" / "/>
<Label Content="현재 색상 : "/>
<Label x:Name="newColor"/>
<Label Content=""/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Label Content="이전 Line : "/>
<CheckBox x:Name="old_chk_01" Content="Line_01" IsEnabled="False" Margin="5,5,5,5"/>
<CheckBox x:Name="old_chk_02" Content="Line_02" IsEnabled="False" Margin="5,5,5,5"/>
<CheckBox x:Name="old_chk_03" Content="Line_03" IsEnabled="False" Margin="5,5,5,5"/>
<CheckBox x:Name="old_chk_04" Content="Line_04" IsEnabled="False" Margin="5,5,5,5"/>
</StackPanel>
</StackPanel>
</Window>
- MainWindow.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace DependencyPropertyEx
{
public class CheckBoxStatus
{
public bool chk_01 { get; set; }
public bool chk_02 { get; set; }
public bool chk_03 { get; set; }
public bool chk_04 { get; set; }
}
public partial class MainWindow : Window
{
private static SolidColorBrush solidColor;
private static SolidColorBrush defaultColor = new SolidColorBrush(Colors.Gray);
public string selectColor
{
get { return (string)GetValue(selectColorProperty); }
set { SetValue(selectColorProperty, value); }
}
public static readonly DependencyProperty selectColorProperty = DependencyProperty.Register(
"selectColor", // DependencyProperty로 등록할 Wrapper 속성 이름
typeof(string), // DependencyProperty 속성 타입
typeof(MainWindow), // DependencyProperty가 속해있는 ownerType
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(SelectColorPropertyChanged))
); // FrameworkPropertyMetadata(속성의 초기값, 속성이 변경 될때 호출할 callback method)
public CheckBoxStatus checkStatus
{
get { return (CheckBoxStatus)GetValue(checkStatusProperty); }
set { SetValue(checkStatusProperty, value); }
}
public static readonly DependencyProperty checkStatusProperty = DependencyProperty.Register(
"checkStatus", // DependencyProperty로 등록할 Wrapper 속성 이름
typeof(CheckBoxStatus), // DependencyProperty 속성 타입
typeof(MainWindow), // DependencyProperty가 속해있는 ownerType
new FrameworkPropertyMetadata(new PropertyChangedCallback(CheckStatusPropertyChanged))
); // FrameworkPropertyMetadata(속성이 변경 될때 호출할 callback method)
// selectColor에 변화가 있으면 호출하는 callback method
private static void SelectColorPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
MainWindow mainWindow = obj as MainWindow;
// 이전 색상 정보
if (e.OldValue == null)
mainWindow.oldColor.Content = "없음";
else
{
mainWindow.oldColor.Content = e.OldValue.ToString();
mainWindow.oldColor.Foreground =
(SolidColorBrush)new BrushConverter().ConvertFromString(e.OldValue.ToString());
}
// 새로운 색상 정보
mainWindow.newColor.Content = e.NewValue.ToString();
solidColor = (SolidColorBrush)new BrushConverter().ConvertFromString(e.NewValue.ToString());
mainWindow.newColor.Foreground = solidColor;
// checkbox 선택 확인 후 색상 적용
mainWindow.br_01.BorderBrush = (mainWindow.chk_01.IsChecked == true) ? solidColor : defaultColor;
mainWindow.br_02.BorderBrush = (mainWindow.chk_02.IsChecked == true) ? solidColor : defaultColor;
mainWindow.br_03.BorderBrush = (mainWindow.chk_03.IsChecked == true) ? solidColor : defaultColor;
mainWindow.br_04.BorderBrush = (mainWindow.chk_04.IsChecked == true) ? solidColor : defaultColor;
}
// checkStatus 변화가 있으면 호출하는 callback method
private static void CheckStatusPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
MainWindow mainWindow = obj as MainWindow;
// 이전 checkbox 정보
if (e.OldValue == null)
{
mainWindow.old_chk_01.IsChecked = false;
mainWindow.old_chk_02.IsChecked = false;
mainWindow.old_chk_03.IsChecked = false;
mainWindow.old_chk_04.IsChecked = false;
}
else
{
CheckBoxStatus oldStatus = e.OldValue as CheckBoxStatus;
mainWindow.old_chk_01.IsChecked = (oldStatus.chk_01 == true) ? true : false;
mainWindow.old_chk_02.IsChecked = (oldStatus.chk_02 == true) ? true : false;
mainWindow.old_chk_03.IsChecked = (oldStatus.chk_03 == true) ? true : false;
mainWindow.old_chk_04.IsChecked = (oldStatus.chk_04 == true) ? true : false;
}
// checkbox 선택 확인 후 색상 적용
mainWindow.br_01.BorderBrush = (mainWindow.chk_01.IsChecked == true) ? solidColor : defaultColor;
mainWindow.br_02.BorderBrush = (mainWindow.chk_02.IsChecked == true) ? solidColor : defaultColor;
mainWindow.br_03.BorderBrush = (mainWindow.chk_03.IsChecked == true) ? solidColor : defaultColor;
mainWindow.br_04.BorderBrush = (mainWindow.chk_04.IsChecked == true) ? solidColor : defaultColor;
}
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MainWindow mainWindow = this;
foreach(RadioButton item in mainWindow.radioGroup.Children)
{
if(item.IsChecked == true)
{
selectColor = item.Content.ToString(); // radioButton에서 체크한 색상 정보 대입
break;
}
}
// 새로운 CheckBoxStatus 생성,
checkStatus = new CheckBoxStatus();
checkStatus.chk_01 = (mainWindow.chk_01.IsChecked == true) ? true : false;
checkStatus.chk_02 = (mainWindow.chk_02.IsChecked == true) ? true : false;
checkStatus.chk_03 = (mainWindow.chk_03.IsChecked == true) ? true : false;
checkStatus.chk_04 = (mainWindow.chk_04.IsChecked == true) ? true : false;
}
}
}
- radiobuon(Red), Line01(CheckBox) 선택, 적용
- radiobuon(Blue), Line01, Line02(CheckBox) 선택, 적용
- radiobuon(Green), Line01, Line02, Line04(CheckBox) 선택, 적용
- radiobuon(Yellow), Line01, Line02, Line03, Line04(CheckBox) 선택, 적용
- radiobuon(Blue), Line01, Line04(CheckBox) 선택, 적용
'개인공부 > WPF' 카테고리의 다른 글
[WPF] DataContext (0) | 2022.07.23 |
---|---|
[WPF] 이벤트 라우팅, 터널링(Tunneling), 버블링(Bubbling) (0) | 2022.05.29 |
[WPF] 멀티쓰레드(Multi Thread) (0) | 2022.05.11 |
[WPF] 데이터 바인딩(Data Binding) (0) | 2022.04.26 |
[WPF] Hello World (0) | 2022.04.19 |