e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
392 lines
14 KiB
C#
392 lines
14 KiB
C#
#region Using directives
|
|
|
|
using System;
|
|
using System.Text;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.ComponentModel;
|
|
using System.Globalization;
|
|
using System.Reflection;
|
|
using System.Runtime.Serialization;
|
|
using System.Workflow.ComponentModel.Compiler;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Security.Permissions;
|
|
|
|
#endregion
|
|
|
|
namespace System.Workflow.ComponentModel
|
|
{
|
|
//
|
|
|
|
[Serializable]
|
|
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
|
|
public sealed class DependencyProperty : ISerializable
|
|
{
|
|
private static IDictionary<int, DependencyProperty> dependencyProperties = new Dictionary<int, DependencyProperty>();
|
|
|
|
internal enum PropertyValidity
|
|
{
|
|
Uninitialize,
|
|
Reexecute,
|
|
Always
|
|
}
|
|
|
|
class KnownDependencyProperty
|
|
{
|
|
internal DependencyProperty dependencyProperty;
|
|
//indicates whether this property, survives beyond Uninitialize.
|
|
internal PropertyValidity propertyValidity;
|
|
|
|
internal KnownDependencyProperty(DependencyProperty dependencyProperty, PropertyValidity propertyValidity)
|
|
{
|
|
this.dependencyProperty = dependencyProperty;
|
|
this.propertyValidity = propertyValidity;
|
|
}
|
|
}
|
|
|
|
private static KnownDependencyProperty[] knownProperties = new KnownDependencyProperty[256];
|
|
|
|
private bool isRegistered = false;
|
|
private string name = String.Empty;
|
|
private System.Type propertyType = null;
|
|
private System.Type ownerType = null;
|
|
private System.Type validatorType = null;
|
|
private PropertyMetadata defaultMetadata = null;
|
|
private byte knownIndex = (byte)0;
|
|
[NonSerialized]
|
|
private bool isEvent = false;
|
|
|
|
public static DependencyProperty Register(string name, System.Type propertyType, System.Type ownerType)
|
|
{
|
|
return ValidateAndRegister(name, propertyType, ownerType, null, null, true);
|
|
}
|
|
|
|
public static DependencyProperty Register(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata)
|
|
{
|
|
return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, null, true);
|
|
}
|
|
|
|
public static DependencyProperty RegisterAttached(string name, System.Type propertyType, System.Type ownerType)
|
|
{
|
|
return ValidateAndRegister(name, propertyType, ownerType, null, null, false);
|
|
}
|
|
|
|
public static DependencyProperty RegisterAttached(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata)
|
|
{
|
|
return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, null, false);
|
|
}
|
|
|
|
internal static void RegisterAsKnown(DependencyProperty dependencyProperty, byte byteVal, PropertyValidity propertyValidity)
|
|
{
|
|
if (dependencyProperty == null)
|
|
throw new ArgumentNullException("dependencyProperty");
|
|
if (knownProperties[byteVal] != null)
|
|
{
|
|
throw new InvalidOperationException(SR.GetString(SR.Error_AlreadyRegisteredAs, knownProperties[byteVal].dependencyProperty.ToString()));
|
|
}
|
|
|
|
dependencyProperty.KnownIndex = byteVal;
|
|
knownProperties[byteVal] = new KnownDependencyProperty(dependencyProperty, propertyValidity);
|
|
}
|
|
|
|
internal static DependencyProperty FromKnown(Byte byteVal)
|
|
{
|
|
if (knownProperties[byteVal] == null)
|
|
{
|
|
throw new InvalidOperationException(SR.GetString(SR.Error_NotRegisteredAs, knownProperties[byteVal].dependencyProperty.ToString()));
|
|
}
|
|
|
|
return knownProperties[byteVal].dependencyProperty;
|
|
}
|
|
|
|
//TBD: Dharma - Get rid of this overload
|
|
public static DependencyProperty RegisterAttached(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata, System.Type validatorType)
|
|
{
|
|
if (validatorType == null)
|
|
throw new ArgumentNullException("validatorType");
|
|
else if (!typeof(Validator).IsAssignableFrom(validatorType))
|
|
throw new ArgumentException(SR.GetString(SR.Error_ValidatorTypeIsInvalid), "validatorType");
|
|
|
|
return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, validatorType, false);
|
|
}
|
|
|
|
public static DependencyProperty FromName(string propertyName, Type ownerType)
|
|
{
|
|
if (propertyName == null)
|
|
throw new ArgumentNullException("propertyName");
|
|
|
|
if (ownerType == null)
|
|
throw new ArgumentNullException("ownerType");
|
|
|
|
DependencyProperty dp = null;
|
|
while ((dp == null) && (ownerType != null))
|
|
{
|
|
// Ensure static constructor of type has run
|
|
RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle);
|
|
|
|
// Locate property
|
|
int hashCode = propertyName.GetHashCode() ^ ownerType.GetHashCode();
|
|
lock (((ICollection)DependencyProperty.dependencyProperties).SyncRoot)
|
|
{
|
|
if (DependencyProperty.dependencyProperties.ContainsKey(hashCode))
|
|
dp = DependencyProperty.dependencyProperties[hashCode];
|
|
}
|
|
|
|
ownerType = ownerType.BaseType;
|
|
}
|
|
|
|
return dp;
|
|
}
|
|
|
|
public static IList<DependencyProperty> FromType(Type ownerType)
|
|
{
|
|
if (ownerType == null)
|
|
throw new ArgumentNullException("ownerType");
|
|
|
|
// Ensure static constructor of type has run
|
|
RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle);
|
|
|
|
List<DependencyProperty> filteredProperties = new List<DependencyProperty>();
|
|
lock (((ICollection)DependencyProperty.dependencyProperties).SyncRoot)
|
|
{
|
|
foreach (DependencyProperty dependencyProperty in DependencyProperty.dependencyProperties.Values)
|
|
{
|
|
if (TypeProvider.IsSubclassOf(ownerType, dependencyProperty.ownerType)
|
|
|| ownerType == dependencyProperty.ownerType)
|
|
filteredProperties.Add(dependencyProperty);
|
|
}
|
|
}
|
|
|
|
return filteredProperties.AsReadOnly();
|
|
}
|
|
|
|
private static DependencyProperty ValidateAndRegister(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata, System.Type validatorType, bool isRegistered)
|
|
{
|
|
if (name == null)
|
|
throw new ArgumentNullException("name");
|
|
|
|
if (name.Length == 0)
|
|
throw new ArgumentException(SR.GetString(SR.Error_EmptyArgument), "name");
|
|
|
|
if (propertyType == null)
|
|
throw new ArgumentNullException("propertyType");
|
|
|
|
if (ownerType == null)
|
|
throw new ArgumentNullException("ownerType");
|
|
|
|
FieldInfo fieldInfo = null;
|
|
bool isEvent = (typeof(System.Delegate).IsAssignableFrom(propertyType) && (defaultMetadata == null || (defaultMetadata.Options & DependencyPropertyOptions.DelegateProperty) == 0));
|
|
|
|
// WinOE Bug 13807: events can not be meta properties.
|
|
if (isEvent && defaultMetadata != null && defaultMetadata.IsMetaProperty)
|
|
throw new ArgumentException(SR.GetString(SR.Error_DPAddHandlerMetaProperty), "defaultMetadata");
|
|
|
|
//Field must exists
|
|
if (isEvent)
|
|
fieldInfo = ownerType.GetField(name + "Event", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.GetProperty);
|
|
else
|
|
fieldInfo = ownerType.GetField(name + "Property", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.GetProperty);
|
|
|
|
if (fieldInfo == null)
|
|
{
|
|
string error = SR.GetString((isEvent) ? SR.Error_DynamicEventNotSupported : SR.Error_DynamicPropertyNotSupported, new object[] { ownerType.FullName, name });
|
|
throw new ArgumentException(error, "ownerType");
|
|
}
|
|
|
|
|
|
PropertyMetadata metadata = null;
|
|
object defaultValue = null;
|
|
|
|
// Establish default metadata for all types, if none is provided
|
|
if (defaultMetadata == null)
|
|
{
|
|
defaultValue = GetDefaultValue(name, propertyType, ownerType);
|
|
metadata = new PropertyMetadata(defaultValue);
|
|
}
|
|
else
|
|
{
|
|
metadata = defaultMetadata;
|
|
if (metadata.DefaultValue == null)
|
|
metadata.DefaultValue = GetDefaultValue(name, propertyType, ownerType);
|
|
}
|
|
|
|
DependencyProperty dependencyProperty = new DependencyProperty(name, propertyType, ownerType, metadata, validatorType, isRegistered);
|
|
lock (((ICollection)DependencyProperty.dependencyProperties).SyncRoot)
|
|
{
|
|
if (DependencyProperty.dependencyProperties.ContainsKey(dependencyProperty.GetHashCode()))
|
|
throw new InvalidOperationException(SR.GetString(SR.Error_DPAlreadyExist, new object[] { name, ownerType.FullName }));
|
|
|
|
DependencyProperty.dependencyProperties.Add(dependencyProperty.GetHashCode(), dependencyProperty);
|
|
}
|
|
|
|
return dependencyProperty;
|
|
}
|
|
|
|
private static object GetDefaultValue(string name, System.Type propertyType, System.Type ownerType)
|
|
{
|
|
if (name == null)
|
|
throw new ArgumentNullException("name");
|
|
|
|
if (name.Length == 0)
|
|
throw new ArgumentException(SR.GetString(SR.Error_EmptyArgument), "name");
|
|
|
|
if (propertyType == null)
|
|
throw new ArgumentNullException("propertyType");
|
|
|
|
if (ownerType == null)
|
|
throw new ArgumentNullException("ownerType");
|
|
|
|
object defaultValue = null;
|
|
if (propertyType.IsValueType)
|
|
{
|
|
try
|
|
{
|
|
if (propertyType.IsEnum)
|
|
{
|
|
Array values = Enum.GetValues(propertyType);
|
|
if (values.Length > 0)
|
|
defaultValue = values.GetValue(0);
|
|
else
|
|
defaultValue = Activator.CreateInstance(propertyType);
|
|
}
|
|
else
|
|
defaultValue = Activator.CreateInstance(propertyType);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
return defaultValue;
|
|
}
|
|
|
|
private DependencyProperty(string name, System.Type propertyType, System.Type ownerType, PropertyMetadata defaultMetadata, System.Type validatorType, bool isRegistered)
|
|
{
|
|
this.name = name;
|
|
this.propertyType = propertyType;
|
|
this.ownerType = ownerType;
|
|
this.validatorType = validatorType;
|
|
this.isRegistered = isRegistered;
|
|
this.defaultMetadata = defaultMetadata;
|
|
this.defaultMetadata.Seal(this, propertyType);
|
|
this.isEvent = (typeof(System.Delegate).IsAssignableFrom(this.propertyType) && (this.defaultMetadata == null || (this.defaultMetadata.Options & DependencyPropertyOptions.DelegateProperty) == 0));
|
|
}
|
|
|
|
public bool IsEvent
|
|
{
|
|
get
|
|
{
|
|
return this.isEvent;
|
|
}
|
|
}
|
|
|
|
public bool IsAttached
|
|
{
|
|
get
|
|
{
|
|
return !this.isRegistered;
|
|
}
|
|
}
|
|
|
|
public string Name
|
|
{
|
|
get
|
|
{
|
|
return this.name;
|
|
}
|
|
}
|
|
|
|
public System.Type PropertyType
|
|
{
|
|
get
|
|
{
|
|
return this.propertyType;
|
|
}
|
|
}
|
|
public System.Type OwnerType
|
|
{
|
|
get
|
|
{
|
|
return this.ownerType;
|
|
}
|
|
}
|
|
|
|
public PropertyMetadata DefaultMetadata
|
|
{
|
|
get
|
|
{
|
|
return this.defaultMetadata;
|
|
}
|
|
}
|
|
public System.Type ValidatorType
|
|
{
|
|
get
|
|
{
|
|
return this.validatorType;
|
|
}
|
|
}
|
|
internal byte KnownIndex
|
|
{
|
|
get
|
|
{
|
|
return this.knownIndex;
|
|
}
|
|
set
|
|
{
|
|
this.knownIndex = value;
|
|
}
|
|
}
|
|
|
|
internal bool IsKnown
|
|
{
|
|
get
|
|
{
|
|
return (this.knownIndex != 0);
|
|
}
|
|
}
|
|
|
|
internal PropertyValidity Validity
|
|
{
|
|
get
|
|
{
|
|
return IsKnown ? knownProperties[this.knownIndex].propertyValidity : PropertyValidity.Always;
|
|
}
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return this.name;
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
//
|
|
|
|
Debug.Assert(this.name != null && this.ownerType != null);
|
|
return (this.name.GetHashCode() ^ this.ownerType.GetHashCode());
|
|
}
|
|
|
|
#region ISerializable Members
|
|
|
|
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
|
|
{
|
|
info.AddValue("type", this.ownerType);
|
|
info.AddValue("name", this.name);
|
|
info.SetType(typeof(DependencyPropertyReference));
|
|
}
|
|
#endregion
|
|
|
|
[Serializable]
|
|
private sealed class DependencyPropertyReference : IObjectReference
|
|
{
|
|
private Type type = null;
|
|
private string name = null;
|
|
|
|
public Object GetRealObject(StreamingContext context)
|
|
{
|
|
return DependencyProperty.FromName(this.name, this.type);
|
|
}
|
|
}
|
|
}
|
|
}
|