[NUI] Introduce CollectionView and related classes. (#2525)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Template / ElementTemplate.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using Tizen.NUI.Binding.Internals;
5
6 namespace Tizen.NUI.Binding
7 {
8     /// <summary>
9     /// Base class for DataTemplate and ControlTemplate classes.
10     /// </summary>
11     [EditorBrowsable(EditorBrowsableState.Never)]
12     public class ElementTemplate : IElement, IDataTemplate
13     {
14         List<Action<object, ResourcesChangedEventArgs>> _changeHandlers;
15         Element _parent;
16         bool _canRecycle; // aka IsDeclarative
17
18         internal ElementTemplate()
19         {
20         }
21
22         internal ElementTemplate(Type type) : this()
23         {
24             if (type == null)
25                 throw new ArgumentNullException(nameof(type));
26
27             _canRecycle = true;
28
29             LoadTemplate = () => Activator.CreateInstance(type);
30         }
31
32         internal ElementTemplate(Func<object> loadTemplate) : this()
33         {
34             if (loadTemplate == null)
35                 throw new ArgumentNullException(nameof(loadTemplate));
36
37             LoadTemplate = loadTemplate;
38         }
39
40         Func<object> LoadTemplate { get; set; }
41
42 #pragma warning disable 0612
43         Func<object> IDataTemplate.LoadTemplate
44         {
45             get { return LoadTemplate; }
46             set { LoadTemplate = value; }
47         }
48 #pragma warning restore 0612
49
50         void IElement.AddResourcesChangedListener(Action<object, ResourcesChangedEventArgs> onchanged)
51         {
52             _changeHandlers = _changeHandlers ?? new List<Action<object, ResourcesChangedEventArgs>>(1);
53             _changeHandlers.Add(onchanged);
54         }
55
56         internal bool CanRecycle => _canRecycle;
57         Element IElement.Parent
58         {
59             get { return _parent; }
60             set
61             {
62                 if (_parent == value)
63                     return;
64                 if (_parent != null)
65                     ((IElement)_parent).RemoveResourcesChangedListener(OnResourcesChanged);
66                 _parent = value;
67                 if (_parent != null)
68                     ((IElement)_parent).AddResourcesChangedListener(OnResourcesChanged);
69             }
70         }
71
72         void IElement.RemoveResourcesChangedListener(Action<object, ResourcesChangedEventArgs> onchanged)
73         {
74             if (_changeHandlers == null)
75                 return;
76             _changeHandlers.Remove(onchanged);
77         }
78
79         /// <summary>
80         /// Used by the XAML infrastructure to load data templates and set up the content of the resulting UI.
81         /// </summary>
82         /// <returns></returns>
83         [EditorBrowsable(EditorBrowsableState.Never)]
84         public object CreateContent()
85         {
86             if (LoadTemplate == null)
87                 throw new InvalidOperationException("LoadTemplate should not be null");
88             if (this is DataTemplateSelector)
89                 throw new InvalidOperationException("Cannot call CreateContent directly on a DataTemplateSelector");
90
91             object item = LoadTemplate();
92             SetupContent(item);
93
94             return item;
95         }
96
97         internal virtual void SetupContent(object item)
98         {
99         }
100
101         void OnResourcesChanged(object sender, ResourcesChangedEventArgs e)
102         {
103             if (_changeHandlers == null)
104                 return;
105             foreach (Action<object, ResourcesChangedEventArgs> handler in _changeHandlers)
106                 handler(this, e);
107         }
108     }
109 }