551ae0be3ed661070932bd47c829ad701f84d5bf
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / XamlBinding / TemplateBinding.cs
1 using System;
2 using System.Globalization;
3
4 namespace Tizen.NUI.Binding
5 {
6     internal class TemplateBinding : BindingBase
7     {
8         internal const string SelfPath = ".";
9         IValueConverter _converter;
10         object _converterParameter;
11
12         BindingExpression _expression;
13         string _path;
14
15         public TemplateBinding()
16         {
17         }
18
19         public TemplateBinding(string path, BindingMode mode = BindingMode.Default, IValueConverter converter = null, object converterParameter = null, string stringFormat = null)
20         {
21             if (path == null)
22                 throw new ArgumentNullException(nameof(path));
23             if (string.IsNullOrWhiteSpace(path))
24                 throw new ArgumentException("path can not be an empty string", nameof(path));
25
26             AllowChaining = true;
27             Path = path;
28             Converter = converter;
29             ConverterParameter = converterParameter;
30             Mode = mode;
31             StringFormat = stringFormat;
32         }
33
34         public IValueConverter Converter
35         {
36             get { return _converter; }
37             set
38             {
39                 ThrowIfApplied();
40
41                 _converter = value;
42             }
43         }
44
45         public object ConverterParameter
46         {
47             get { return _converterParameter; }
48             set
49             {
50                 ThrowIfApplied();
51
52                 _converterParameter = value;
53             }
54         }
55
56         public string Path
57         {
58             get { return _path; }
59             set
60             {
61                 ThrowIfApplied();
62
63                 _path = value;
64                 _expression = GetBindingExpression(value);
65             }
66         }
67
68         internal override void Apply(bool fromTarget)
69         {
70             base.Apply(fromTarget);
71
72             if (_expression == null)
73                 _expression = new BindingExpression(this, SelfPath);
74
75             _expression.Apply(fromTarget);
76         }
77
78         internal override async void Apply(object newContext, BindableObject bindObj, BindableProperty targetProperty, bool fromBindingContextChanged = false)
79         {
80             var view = bindObj as Element;
81             if (view == null)
82                 throw new InvalidOperationException();
83
84             base.Apply(newContext, bindObj, targetProperty, fromBindingContextChanged);
85
86             Element templatedParent = await TemplateUtilities.FindTemplatedParentAsync(view).ConfigureAwait(false);
87             ApplyInner(templatedParent, bindObj, targetProperty);
88         }
89
90         internal override BindingBase Clone()
91         {
92             return new TemplateBinding(Path, Mode) { Converter = Converter, ConverterParameter = ConverterParameter, StringFormat = StringFormat };
93         }
94
95         internal override object GetSourceValue(object value, Type targetPropertyType)
96         {
97             if (Converter != null)
98                 value = Converter.Convert(value, targetPropertyType, ConverterParameter, CultureInfo.CurrentUICulture);
99
100             return base.GetSourceValue(value, targetPropertyType);
101         }
102
103         internal override object GetTargetValue(object value, Type sourcePropertyType)
104         {
105             if (Converter != null)
106                 value = Converter.ConvertBack(value, sourcePropertyType, ConverterParameter, CultureInfo.CurrentUICulture);
107
108             return base.GetTargetValue(value, sourcePropertyType);
109         }
110
111         internal override void Unapply(bool fromBindingContextChanged = false)
112         {
113             base.Unapply(fromBindingContextChanged: fromBindingContextChanged);
114
115             if (_expression != null)
116                 _expression.Unapply();
117         }
118
119         void ApplyInner(Element templatedParent, BindableObject bindableObject, BindableProperty targetProperty)
120         {
121             if (_expression == null && templatedParent != null)
122                 _expression = new BindingExpression(this, SelfPath);
123
124             _expression?.Apply(templatedParent, bindableObject, targetProperty);
125         }
126
127         BindingExpression GetBindingExpression(string path)
128         {
129             return new BindingExpression(this, !string.IsNullOrWhiteSpace(path) ? path : SelfPath);
130         }
131     }
132 }