2010-06-03 Jb Evain <jbevain@novell.com>
[mcs.git] / class / WindowsBase / System.Windows / DependencyProperty.cs
blob3f968eaa83acf96da4f871385ccee0410a0d7d4e
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // (C) 2005 Iain McCoy
22 // Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
24 // Authors:
25 // Iain McCoy (iain@mccoy.id.au)
26 // Chris Toshok (toshok@ximian.com)
29 using System.Collections.Generic;
31 namespace System.Windows {
32 public sealed class DependencyProperty {
33 private Dictionary<Type,PropertyMetadata> metadataByType = new Dictionary<Type,PropertyMetadata>();
35 public static readonly object UnsetValue = new object ();
37 private DependencyProperty (bool isAttached, string name, Type propertyType, Type ownerType,
38 PropertyMetadata defaultMetadata,
39 ValidateValueCallback validateValueCallback)
41 IsAttached = isAttached;
42 DefaultMetadata = (defaultMetadata == null ? new PropertyMetadata() : defaultMetadata);
43 Name = name;
44 OwnerType = ownerType;
45 PropertyType = propertyType;
46 ValidateValueCallback = validateValueCallback;
49 internal bool IsAttached { get; set; }
50 public bool ReadOnly { get; private set; }
51 public PropertyMetadata DefaultMetadata { get; private set; }
52 public string Name { get; private set; }
53 public Type OwnerType { get; private set; }
54 public Type PropertyType { get; private set; }
55 public ValidateValueCallback ValidateValueCallback { get; private set; }
57 public int GlobalIndex {
58 get { throw new NotImplementedException (); }
62 public DependencyProperty AddOwner(Type ownerType)
64 return AddOwner (ownerType, null);
67 public DependencyProperty AddOwner(Type ownerType, PropertyMetadata typeMetadata)
69 if (typeMetadata == null) typeMetadata = new PropertyMetadata ();
70 OverrideMetadata (ownerType, typeMetadata);
72 // MS seems to always return the same DependencyProperty
73 return this;
76 public PropertyMetadata GetMetadata(Type forType)
78 if (metadataByType.ContainsKey (forType))
79 return metadataByType[forType];
80 return null;
83 public PropertyMetadata GetMetadata(DependencyObject d)
85 if (metadataByType.ContainsKey (d.GetType()))
86 return metadataByType[d.GetType()];
87 return null;
90 public PropertyMetadata GetMetadata(DependencyObjectType dependencyObjectType)
92 if (metadataByType.ContainsKey (dependencyObjectType.SystemType))
93 return metadataByType[dependencyObjectType.SystemType];
94 return null;
98 public bool IsValidType(object value)
100 return PropertyType.IsInstanceOfType (value);
103 public bool IsValidValue(object value)
105 if (!IsValidType (value))
106 return false;
107 if (ValidateValueCallback == null)
108 return true;
109 return ValidateValueCallback (value);
112 public void OverrideMetadata(Type forType, PropertyMetadata typeMetadata)
114 if (forType == null)
115 throw new ArgumentNullException ("forType");
116 if (typeMetadata == null)
117 throw new ArgumentNullException ("typeMetadata");
119 if (ReadOnly)
120 throw new InvalidOperationException (String.Format ("Cannot override metadata on readonly property '{0}' without using a DependencyPropertyKey", Name));
122 typeMetadata.DoMerge (DefaultMetadata, this, forType);
123 metadataByType.Add (forType, typeMetadata);
126 public void OverrideMetadata (Type forType, PropertyMetadata typeMetadata, DependencyPropertyKey key)
128 if (forType == null)
129 throw new ArgumentNullException ("forType");
130 if (typeMetadata == null)
131 throw new ArgumentNullException ("typeMetadata");
134 // further checking? should we check
135 // key.DependencyProperty == this?
137 typeMetadata.DoMerge (DefaultMetadata, this, forType);
138 metadataByType.Add (forType, typeMetadata);
141 public override string ToString ()
143 return Name;
146 public override int GetHashCode ()
148 return Name.GetHashCode() ^ PropertyType.GetHashCode() ^ OwnerType.GetHashCode();
151 public static DependencyProperty Register(string name, Type propertyType, Type ownerType)
153 return Register(name, propertyType, ownerType, null, null);
156 public static DependencyProperty Register(string name, Type propertyType, Type ownerType,
157 PropertyMetadata typeMetadata)
159 return Register(name, propertyType, ownerType, typeMetadata, null);
162 public static DependencyProperty Register(string name, Type propertyType, Type ownerType,
163 PropertyMetadata typeMetadata,
164 ValidateValueCallback validateValueCallback)
166 if (typeMetadata == null)
167 typeMetadata = new PropertyMetadata();
169 DependencyProperty dp = new DependencyProperty(false, name, propertyType, ownerType,
170 typeMetadata, validateValueCallback);
171 DependencyObject.register(ownerType, dp);
173 dp.OverrideMetadata (ownerType, typeMetadata);
175 return dp;
178 public static DependencyProperty RegisterAttached(string name, Type propertyType, Type ownerType)
180 return RegisterAttached(name, propertyType, ownerType, null, null);
183 public static DependencyProperty RegisterAttached(string name, Type propertyType, Type ownerType,
184 PropertyMetadata defaultMetadata)
186 return RegisterAttached(name, propertyType, ownerType, defaultMetadata, null);
189 public static DependencyProperty RegisterAttached(string name, Type propertyType, Type ownerType,
190 PropertyMetadata defaultMetadata,
191 ValidateValueCallback validateValueCallback)
193 DependencyProperty dp = new DependencyProperty(true, name, propertyType, ownerType,
194 defaultMetadata, validateValueCallback);
195 DependencyObject.register(ownerType, dp);
196 return dp;
199 public static DependencyPropertyKey RegisterAttachedReadOnly(string name, Type propertyType, Type ownerType,
200 PropertyMetadata defaultMetadata)
202 throw new NotImplementedException("RegisterAttachedReadOnly(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata)");
205 public static DependencyPropertyKey RegisterAttachedReadOnly(string name, Type propertyType, Type ownerType,
206 PropertyMetadata defaultMetadata,
207 ValidateValueCallback validateValueCallback)
209 throw new NotImplementedException("RegisterAttachedReadOnly(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback)");
212 public static DependencyPropertyKey RegisterReadOnly(string name, Type propertyType, Type ownerType,
213 PropertyMetadata typeMetadata)
215 return RegisterReadOnly (name, propertyType, ownerType, typeMetadata, null);
219 public static DependencyPropertyKey RegisterReadOnly(string name, Type propertyType, Type ownerType,
220 PropertyMetadata typeMetadata,
221 ValidateValueCallback validateValueCallback)
223 DependencyProperty prop = Register (name, propertyType, ownerType, typeMetadata, validateValueCallback);
224 prop.ReadOnly = true;
225 return new DependencyPropertyKey (prop);