93a2355f82044574e0fabc20e8d947c6cf7c6379
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / XamlBinding / BindingBase.cs
1 using System;
2 using System.Collections;
3 using System.Runtime.CompilerServices;
4 using System.ComponentModel;
5
6 namespace Tizen.NUI.Binding
7 {
8     /// <summary>
9     /// An abstract class that provides a BindingMode and a formatting option.
10     /// </summary>
11     [EditorBrowsable(EditorBrowsableState.Never)]
12     internal abstract class BindingBase
13     {
14         static readonly ConditionalWeakTable<IEnumerable, CollectionSynchronizationContext> SynchronizedCollections = new ConditionalWeakTable<IEnumerable, CollectionSynchronizationContext>();
15
16         BindingMode _mode = BindingMode.Default;
17         string _stringFormat;
18         object _targetNullValue;
19         object _fallbackValue;
20
21         internal BindingBase()
22         {
23         }
24
25         /// <summary>
26         /// Gets or sets the mode for this binding.
27         /// </summary>
28         public BindingMode Mode
29         {
30             get { return _mode; }
31             set
32             {
33                 if (   value != BindingMode.Default
34                     && value != BindingMode.OneWay
35                     && value != BindingMode.OneWayToSource
36                     && value != BindingMode.TwoWay
37                     && value != BindingMode.OneTime)
38                     throw new ArgumentException("mode is not a valid BindingMode", "mode");
39
40                 ThrowIfApplied();
41
42                 _mode = value;
43             }
44         }
45
46         /// <summary>
47         /// Gets or sets the string format for this binding.
48         /// </summary>
49         public string StringFormat
50         {
51             get { return _stringFormat; }
52             set
53             {
54                 ThrowIfApplied();
55
56                 _stringFormat = value;
57             }
58         }
59
60                 public object TargetNullValue
61                 {
62                         get { return _targetNullValue; }
63                         set {
64                                 ThrowIfApplied();
65                                 _targetNullValue = value;
66                         }
67                 }
68
69                 public object FallbackValue {
70                         get => _fallbackValue;
71                         set {
72                                 ThrowIfApplied();
73                                 _fallbackValue = value;
74                         }
75                 }
76
77                 internal bool AllowChaining { get; set; }
78
79         internal object Context { get; set; }
80
81         internal bool IsApplied { get; private set; }
82
83         /// <summary>
84         /// Stops synchronization on the collection.
85         /// </summary>
86         /// <param name="collection">The collection on which to stop synchronization.</param>
87         public static void DisableCollectionSynchronization(IEnumerable collection)
88         {
89             if (collection == null)
90                 throw new ArgumentNullException(nameof(collection));
91
92             SynchronizedCollections.Remove(collection);
93         }
94
95         public static void EnableCollectionSynchronization(IEnumerable collection, object context, CollectionSynchronizationCallback callback)
96         {
97             if (collection == null)
98                 throw new ArgumentNullException(nameof(collection));
99             if (callback == null)
100                 throw new ArgumentNullException(nameof(callback));
101
102             SynchronizedCollections.Add(collection, new CollectionSynchronizationContext(context, callback));
103         }
104
105         /// <summary>
106         /// Throws an InvalidOperationException if the binding has been applied.
107         /// </summary>
108         protected void ThrowIfApplied()
109         {
110             if (IsApplied)
111                 throw new InvalidOperationException("Can not change a binding while it's applied");
112         }
113
114         internal virtual void Apply(bool fromTarget)
115         {
116             IsApplied = true;
117         }
118
119         internal virtual void Apply(object context, BindableObject bindObj, BindableProperty targetProperty, bool fromBindingContextChanged = false)
120         {
121             IsApplied = true;
122         }
123
124         internal abstract BindingBase Clone();
125
126         internal virtual object GetSourceValue(object value, Type targetPropertyType)
127         {
128             if (value == null && TargetNullValue != null)
129                 return TargetNullValue;
130             if (StringFormat != null)
131                 return string.Format(StringFormat, value);
132
133             return value;
134         }
135
136         internal virtual object GetTargetValue(object value, Type sourcePropertyType)
137         {
138             return value;
139         }
140
141         internal static bool TryGetSynchronizedCollection(IEnumerable collection, out CollectionSynchronizationContext synchronizationContext)
142         {
143             if (collection == null)
144                 throw new ArgumentNullException(nameof(collection));
145
146             return SynchronizedCollections.TryGetValue(collection, out synchronizationContext);
147         }
148
149         internal virtual void Unapply(bool fromBindingContextChanged = false)
150         {
151             IsApplied = false;
152         }
153     }
154 }