minor fix for bug 9520:
[mono.git] / mcs / class / WindowsBase / System.Windows / DependencyObject.cs
1 //
2 // DependencyObject.cs
3 //
4 // Author:
5 //   Iain McCoy (iain@mccoy.id.au)
6 //   Chris Toshok (toshok@ximian.com)
7 //
8 // (C) 2005 Iain McCoy
9 // (C) 2007 Novell, Inc.
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System.Collections.Generic;
32 using System.Windows.Threading;
33
34 namespace System.Windows {
35         public class DependencyObject : DispatcherObject {
36                 private static Dictionary<Type,Dictionary<string,DependencyProperty>> propertyDeclarations = new Dictionary<Type,Dictionary<string,DependencyProperty>>();
37                 private Dictionary<DependencyProperty,object> properties = new Dictionary<DependencyProperty,object>();
38
39                 [MonoTODO]
40                 public bool IsSealed {
41                         get { return false; }
42                 }
43
44                 public DependencyObjectType DependencyObjectType { 
45                         get { return DependencyObjectType.FromSystemType (GetType()); }
46                 }
47
48                 public void ClearValue(DependencyProperty dp)
49                 {
50                         if (IsSealed)
51                                 throw new InvalidOperationException ("Cannot manipulate property values on a sealed DependencyObject");
52
53                         properties[dp] = null;
54                 }
55                 
56                 public void ClearValue(DependencyPropertyKey key)
57                 {
58                         ClearValue (key.DependencyProperty);
59                 }
60
61                 public void CoerceValue (DependencyProperty dp)
62                 {
63                         PropertyMetadata pm = dp.GetMetadata (this);
64                         if (pm.CoerceValueCallback != null)
65                                 pm.CoerceValueCallback (this, GetValue (dp));
66                 }
67
68                 public sealed override bool Equals (object obj)
69                 {
70                         throw new NotImplementedException("Equals");
71                 }
72
73                 public sealed override int GetHashCode ()
74                 {
75                         throw new NotImplementedException("GetHashCode");
76                 }
77
78                 [MonoTODO]
79                 public LocalValueEnumerator GetLocalValueEnumerator()
80                 {
81                         return new LocalValueEnumerator(properties);
82                 }
83                 
84                 public object GetValue(DependencyProperty dp)
85                 {
86                         object val = properties[dp];
87                         return val == null ? dp.DefaultMetadata.DefaultValue : val;
88                 }
89                 
90                 [MonoTODO]
91                 public void InvalidateProperty(DependencyProperty dp)
92                 {
93                         throw new NotImplementedException("InvalidateProperty(DependencyProperty dp)");
94                 }
95                 
96                 protected virtual void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
97                 {
98                         PropertyMetadata pm = e.Property.GetMetadata (this);
99                         if (pm.PropertyChangedCallback != null)
100                                 pm.PropertyChangedCallback (this, e);
101                 }
102                 
103                 public object ReadLocalValue(DependencyProperty dp)
104                 {
105                         object val = properties[dp];
106                         return val == null ? DependencyProperty.UnsetValue : val;
107                 }
108                 
109                 public void SetValue(DependencyProperty dp, object value)
110                 {
111                         if (IsSealed)
112                                 throw new InvalidOperationException ("Cannot manipulate property values on a sealed DependencyObject");
113
114                         if (!dp.IsValidType (value))
115                                 throw new ArgumentException ("value not of the correct type for this DependencyProperty");
116
117                         ValidateValueCallback validate = dp.ValidateValueCallback;
118                         if (validate != null && !validate(value))
119                                 throw new Exception("Value does not validate");
120                         else
121                                 properties[dp] = value;
122                 }
123                 
124                 public void SetValue(DependencyPropertyKey key, object value)
125                 {
126                         SetValue (key.DependencyProperty, value);
127                 }
128
129                 protected virtual bool ShouldSerializeProperty (DependencyProperty dp)
130                 {
131                         throw new NotImplementedException ();
132                 }
133
134                 internal static void register(Type t, DependencyProperty dp)
135                 {
136                         if (!propertyDeclarations.ContainsKey (t))
137                                 propertyDeclarations[t] = new Dictionary<string,DependencyProperty>();
138                         Dictionary<string,DependencyProperty> typeDeclarations = propertyDeclarations[t];
139                         if (!typeDeclarations.ContainsKey(dp.Name))
140                                 typeDeclarations[dp.Name] = dp;
141                         else
142                                 throw new ArgumentException("A property named " + dp.Name + " already exists on " + t.Name);
143                 }
144         }
145 }