DirectionalBinding
이 예제는 바인딩의 데이터 흐름 방향에 대한 설명 입니다. 샘플 프로젝트는 전체 수입에서 지출 내역이 변경 되었을 경우 남은 금액을 계산하는 프로젝트 입니다.
바인딩 객체 정의
TotalIncome, Food, Misc, Rent, Savings 속성을 가지고 있는 NetIncome 객체를 생성 합니다. 속성 변경 알림을 위해 INotifyPropertyChanged를 구현하며 총 수입에서 총 지출액을 뺀 나머지를 계산하는 UpdateSavings 메서드를 구현 합니다.
1: using System;
2: using System.Collections.Generic;
3: using System.ComponentModel;
4: using System.Linq;
5: using System.Text;
6: using System.Threading.Tasks;
7: namespace DirectionalBinding
8: {
9: public class NetIncome : INotifyPropertyChanged
10: {
11: private int _food;
12: private int _misc;
13: private int _rent = 2000;
14: private int _savings;
15: private int _totalIncome = 5000;
16: public int Food
17: {
18: get
19: {
20: return _food;
21: }
22: set
23: {
24: if (Food != value)
25: {
26: _food = value;
27: OnPropertyChanged("Food");
28: UpdateSavings();
29: }
30: }
31: }
32: public int Misc
33: {
34: get
35: {
36: return _misc;
37: }
38: set
39: {
40: if (Misc != value)
41: {
42: _misc = value;
43: OnPropertyChanged("Misc");
44: UpdateSavings();
45: }
46: }
47: }
48: public int Rent
49: {
50: get
51: {
52: return _rent;
53: }
54: set
55: {
56: if (Rent != value)
57: {
58: _rent = value;
59: OnPropertyChanged("Rent");
60: UpdateSavings();
61: }
62: }
63: }
64: public int Savings
65: {
66: get
67: {
68: return _savings;
69: }
70: set
71: {
72: if (Savings != value)
73: {
74: _savings = value;
75: OnPropertyChanged("Savings");
76: UpdateSavings();
77: }
78: }
79: }
80: public int TotalIncome
81: {
82: get
83: {
84: return _totalIncome;
85: }
86: set
87: {
88: if (TotalIncome != value)
89: {
90: _totalIncome = value;
91: OnPropertyChanged("TotalIncome");
92: }
93: }
94: }
95: public NetIncome()
96: {
97: _savings = _totalIncome - (_rent + _food + _misc);
98: }
99: private void UpdateSavings()
100: {
101: Savings = TotalIncome - (Rent + Misc + Food);
102: if (Savings < 0)
103: {
104: }
105: else if (Savings >= 0)
106: { }
107: }
108: public event PropertyChangedEventHandler PropertyChanged;
109: public void OnPropertyChanged(string propertyName)
110: {
111: PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
112: }
113: }
114: }
BindingMode - OneTime
어플리케이션이 시작 되거나 원본값이 변경되지 않는 바인딩 유형 입니다. 예제에서는 TotalIncome 속성이 TextBlock 컨트롤의 Text 속성에 바인딩 됩니다.
<Label Grid.Row="0" Grid.Column="0">Total Income:</Label>
<TextBlock Name="IncomeText" Grid.Row="0" Grid.Column="1" Text="{Binding Path=TotalIncome, Mode=OneTime}" />
<TextBlock Grid.Row="0" Grid.Column="2">OneTime Binding</TextBlock>
BindingMode - OneWay
바인딩 소스(원본)가 변경되면 바인딩 대상 속성이 업데이트 됩니다. 바인딩 되는 컨트롤이 암시적으로 읽기 전용인 경우에 적합 합니다. 예제에서는 Rent 속성이 TextBlock 컨트롤의 Text 속성에 바인딩 되며 명시적으로 Mode 속성으로 OneWay를 설정하고 NotifyOnTargetUpdated 속성을 True 설정을 통해 TextBock.Text 속성이 업데이트 될 때 이벤트를 수신 할 수 있습니다.
<Label Grid.Row="1" Grid.Column="0">Rent</Label>
<TextBlock Grid.Row="1" Grid.Column="1" Name="RentText" Text="{Binding Path=Rent, Mode=OneWay, NotifyOnTargetUpdated=True}" TargetUpdated="OnTargetUpdated" />
<TextBlock Grid.Row="1" Grid.Column="2">OneWay Binding, with TargetUpdated event handling</TextBlock>
private void OnTargetUpdated(object sender, DataTransferEventArgs e)
{
var fe = sender as FrameworkElement;
infoText.Text = "";
infoText.Text += e.Property.Name + " property of a " + e.Property.OwnerType.Name;
infoText.Text += " element (";
infoText.Text += fe.Name;
infoText.Text += ") updated...";
infoText.Text += DateTime.Now.ToLongDateString();
infoText.Text += " at ";
infoText.Text += DateTime.Now.ToLongTimeString();
}
BindingMode - TwoWay (PropertyChanged)
원본 속성 및 대상 속성이 변경되면 다른 항목이 자동으로 업데이트 되도록 합니다. 예제에서는 Food 속성이 TextBox 컨트롤의 Text속성에 바인딩 되며 UpdateSourceTrigger 속성으로 PropertyChanged 설정을 통해 업데이트 이벤트 시점을 속성이 변경 될 때마다 발생하도록 합니다.
Label Grid.Row="2" Grid.Column="0">Food</Label>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=Food, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Grid.Row="2" Grid.Column="2">TwoWay Binding (TextBox default), Update on PropertyChanged</TextBlock>
BindingMode - TwoWay
위에 설명한 TwoWay와 기본 동작은 같다. 유저의 값을 입력 받는 컨트롤(예: TextBox)는 UpdateSourceTrigger 속성이 기본값으로 LostFocus로 설정되어 있다.
<Label Grid.Row="3" Grid.Column="0">Miscellaneous</Label>
<TextBox Grid.Row="3" Grid.Column="1" Name="MiscText" Text="{Binding Path=Misc}"/>
<TextBlock Grid.Row="3" Grid.Column="2">
TwoWay Binding (TextBox default), Update on LostFocus (TextBox default)</TextBlock>
코드에서 바인드 데이터 변경
예제에서는 버튼 이벤트를 통해 Rent 속성을 변경하여 TextBlock.Text 속성을 갱신 하고 UpdateSavings 메서드를 통해 Saving 속성을 업데이트 합니다.
<Button Grid.Row="5" Grid.Column="0" Click="OnRentRaise">Raise the Rent!</Button>
private void OnRentRaise(object sender, RoutedEventArgs e)
{
var randome = new Random();
double i = randome.Next(10);
var bindingExpression = BindingOperations.GetBindingExpression(RentText, TextBlock.TextProperty);
var sourceData = (NetIncome)bindingExpression.DataItem;
sourceData.Rent = (int)((1 + i / 100) * sourceData.Rent);
}
댓글
댓글 쓰기