-
Notifications
You must be signed in to change notification settings - Fork 0
/
EntryAmountControl.xaml.cs
144 lines (127 loc) · 4.36 KB
/
EntryAmountControl.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Data;
namespace Budget
{
public partial class EntryAmount : INotifyPropertyChanged
{
// Note that when assigning to Sum, it's the value UP TO this entry,
// whereas reading from Sum is the value INCLUDING this entry.
private decimal sum;
public decimal Sum
{
get { return sum + Amount; }
set
{
if (sum != value)
{
sum = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Sum"));
}
}
}
/// <summary>
/// Wrapper around Amount that adds PropertyChanged invocations.
/// </summary>
public decimal BoundAmount
{
get { return Amount; }
set
{
if (Amount != value)
{
Amount = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("BoundAmount"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Sum"));
}
}
}
public void Connect(EntryAmount previous)
{
Sum = previous.Sum;
previous.PropertyChanged += propagateSum;
}
public void Disconnect(EntryAmount previous)
{
previous.PropertyChanged -= propagateSum;
}
private void propagateSum(object sender, PropertyChangedEventArgs e)
{
Sum = (sender as EntryAmount).Sum;
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class EntryAmountCollection : Dictionary<Account, EntryAmount>
{
public readonly Entry Owner;
public EntryAmountCollection(Entry owner, Account[] accounts) :
base(owner.Amounts.ToDictionary(x => x.Account))
{
Owner = owner;
foreach (var account in accounts)
{
if (!ContainsKey(account))
Add(account, new EntryAmount() { Entry = owner, Account = account });
this[account].PropertyChanged += syncToOwner;
}
}
public void Connect(Entry previous)
{
foreach (var amount in Values)
amount.Connect(previous.BoundAmounts[amount.Account]);
}
public void Disconnect(Entry previous)
{
foreach (var amount in Values)
amount.Disconnect(previous.BoundAmounts[amount.Account]);
}
private void syncToOwner(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "BoundAmount")
{
EntryAmount amount = sender as EntryAmount;
bool isOwned = Owner.Amounts.Contains(amount);
if (amount.Amount == 0 && isOwned)
Owner.Amounts.Remove(amount);
else if (amount.Amount != 0 && !isOwned)
Owner.Amounts.Add(amount);
}
}
}
public class AmountConverter : IValueConverter
{
private readonly Account account;
public AmountConverter(Account account)
{
this.account = account;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var amounts = value as EntryAmountCollection;
return amounts[account];
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
}
public class AmountEnabledConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value is EntryAmount;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
}
/// <summary>
/// Interaction logic for EntryAmountControl.xaml
/// </summary>
public partial class EntryAmountControl : UserControl
{
public EntryAmountControl()
{
InitializeComponent();
}
}
}