-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
MvxChainedSourceBinding.cs
122 lines (105 loc) · 3.77 KB
/
MvxChainedSourceBinding.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
// MvxChainedSourceBinding.cs
// (c) Copyright Cirrious Ltd. http://www.cirrious.com
// MvvmCross is licensed using Microsoft Public License (Ms-PL)
// Contributions and inspirations noted in readme.md and license.txt
//
// Project Lead - Stuart Lodge, @slodge, me@slodge.com
using System;
using System.Collections.Generic;
using Cirrious.MvvmCross.Binding.Bindings.Source.Construction.PropertyTokens;
using Cirrious.MvvmCross.Binding.Interfaces.Bindings.Source;
using Cirrious.MvvmCross.Binding.Interfaces.Bindings.Source.Construction;
using Cirrious.MvvmCross.ExtensionMethods;
using Cirrious.MvvmCross.Interfaces.Platform.Diagnostics;
using Cirrious.MvvmCross.Interfaces.ServiceProvider;
namespace Cirrious.MvvmCross.Binding.Bindings.Source.Chained
{
public abstract class MvxChainedSourceBinding
: MvxBasePropertyInfoSourceBinding
, IMvxServiceConsumer<IMvxSourceBindingFactory>
{
private readonly IList<MvxBasePropertyToken> _childTokens;
private IMvxSourceBinding _currentChildBinding;
protected MvxChainedSourceBinding(
object source,
string propertyName,
IList<MvxBasePropertyToken> childTokens)
: base(source, propertyName)
{
_childTokens = childTokens;
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
if (_currentChildBinding != null)
{
_currentChildBinding.Dispose();
_currentChildBinding = null;
}
}
base.Dispose(isDisposing);
}
private IMvxSourceBindingFactory SourceBindingFactory
{
get { return this.GetService(); }
}
public override Type SourceType
{
get { throw new NotImplementedException(); }
}
protected void UpdateChildBinding()
{
if (_currentChildBinding != null)
{
_currentChildBinding.Changed -= ChildSourceBindingChanged;
_currentChildBinding.Dispose();
_currentChildBinding = null;
}
if (PropertyInfo == null)
{
return;
}
var currentValue = PropertyInfo.GetValue(Source, PropertyIndexParameters());
if (currentValue == null)
{
// value will be missing... so end consumer will need to use fallback values
return;
}
else
{
_currentChildBinding = SourceBindingFactory.CreateBinding(currentValue, _childTokens);
_currentChildBinding.Changed += ChildSourceBindingChanged;
}
}
protected abstract object[] PropertyIndexParameters();
private void ChildSourceBindingChanged(object sender, MvxSourcePropertyBindingEventArgs e)
{
FireChanged(e);
}
protected override void OnBoundPropertyChanged()
{
UpdateChildBinding();
FireChanged(new MvxSourcePropertyBindingEventArgs(this));
}
public override bool TryGetValue(out object value)
{
if (_currentChildBinding == null)
{
value = null;
return false;
}
return _currentChildBinding.TryGetValue(out value);
}
public override void SetValue(object value)
{
if (_currentChildBinding == null)
{
MvxBindingTrace.Trace(MvxTraceLevel.Warning,
"SetValue ignored in binding - target property path missing");
return;
}
_currentChildBinding.SetValue(value);
}
}
}