Add ScriptUI to support XAML file (#320)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / XamlBinding / Interactivity / AttachedCollection.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Collections.ObjectModel;
4
5 namespace Tizen.NUI.Binding
6 {
7     internal class AttachedCollection<T> : ObservableCollection<T>, ICollection<T>, IAttachedObject where T : BindableObject, IAttachedObject
8     {
9         readonly List<WeakReference> _associatedObjects = new List<WeakReference>();
10
11         public AttachedCollection()
12         {
13         }
14
15         public AttachedCollection(IEnumerable<T> collection) : base(collection)
16         {
17         }
18
19         public AttachedCollection(IList<T> list) : base(list)
20         {
21         }
22
23         public void AttachTo(BindableObject bindable)
24         {
25             if (bindable == null)
26                 throw new ArgumentNullException("bindable");
27             OnAttachedTo(bindable);
28         }
29
30         public void DetachFrom(BindableObject bindable)
31         {
32             OnDetachingFrom(bindable);
33         }
34
35         protected override void ClearItems()
36         {
37             foreach (WeakReference weakbindable in _associatedObjects)
38             {
39                 foreach (T item in this)
40                 {
41                     var bindable = weakbindable.Target as BindableObject;
42                     if (bindable == null)
43                         continue;
44                     item.DetachFrom(bindable);
45                 }
46             }
47             base.ClearItems();
48         }
49
50         protected override void InsertItem(int index, T item)
51         {
52             base.InsertItem(index, item);
53             foreach (WeakReference weakbindable in _associatedObjects)
54             {
55                 var bindable = weakbindable.Target as BindableObject;
56                 if (bindable == null)
57                     continue;
58                 item.AttachTo(bindable);
59             }
60         }
61
62         protected virtual void OnAttachedTo(BindableObject bindable)
63         {
64             lock (_associatedObjects)
65             {
66                 _associatedObjects.Add(new WeakReference(bindable));
67             }
68             foreach (T item in this)
69                 item.AttachTo(bindable);
70         }
71
72         protected virtual void OnDetachingFrom(BindableObject bindable)
73         {
74             foreach (T item in this)
75                 item.DetachFrom(bindable);
76             lock (_associatedObjects)
77             {
78                 for (var i = 0; i < _associatedObjects.Count; i++)
79                 {
80                     object target = _associatedObjects[i].Target;
81
82                     if (target == null || target == bindable)
83                     {
84                         _associatedObjects.RemoveAt(i);
85                         i--;
86                     }
87                 }
88             }
89         }
90
91         protected override void RemoveItem(int index)
92         {
93             T item = this[index];
94             foreach (WeakReference weakbindable in _associatedObjects)
95             {
96                 var bindable = weakbindable.Target as BindableObject;
97                 if (bindable == null)
98                     continue;
99                 item.DetachFrom(bindable);
100             }
101
102             base.RemoveItem(index);
103         }
104
105         protected override void SetItem(int index, T item)
106         {
107             T old = this[index];
108             foreach (WeakReference weakbindable in _associatedObjects)
109             {
110                 var bindable = weakbindable.Target as BindableObject;
111                 if (bindable == null)
112                     continue;
113                 old.DetachFrom(bindable);
114             }
115
116             base.SetItem(index, item);
117
118             foreach (WeakReference weakbindable in _associatedObjects)
119             {
120                 var bindable = weakbindable.Target as BindableObject;
121                 if (bindable == null)
122                     continue;
123                 item.AttachTo(bindable);
124             }
125         }
126     }
127 }