Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / WinForms / Managed / System / WinForms / PropertyGridInternal / MergePropertyDescriptor.cs / 1 / MergePropertyDescriptor.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.Windows.Forms.PropertyGridInternal { using System.Runtime.Serialization.Formatters; using System.Runtime.Serialization.Formatters.Binary; using System.ComponentModel; using System.Diagnostics; using System; using System.IO; using System.Collections; using System.Globalization; using System.Reflection; using System.ComponentModel.Design; using System.ComponentModel.Design.Serialization; using System.Windows.Forms; using System.Drawing; using Microsoft.Win32; internal class MergePropertyDescriptor : PropertyDescriptor { private PropertyDescriptor[] descriptors; private enum TriState { Unknown, Yes, No } private TriState localizable = TriState.Unknown; private TriState readOnly = TriState.Unknown; private TriState canReset = TriState.Unknown; private MultiMergeCollection collection; public MergePropertyDescriptor(PropertyDescriptor[] descriptors) : base(descriptors[0].Name, null) { this.descriptors = descriptors; } ////// /// public override Type ComponentType { get { return descriptors[0].ComponentType; } } ////// When overridden in a derived class, gets the type of the /// component this property /// is bound to. /// ////// /// public override TypeConverter Converter { get { return descriptors[0].Converter; } } public override string DisplayName { get { return descriptors[0].DisplayName; } } ////// Gets the type converter for this property. /// ////// /// public override bool IsLocalizable { get { if (localizable == TriState.Unknown) { localizable = TriState.Yes; foreach (PropertyDescriptor pd in descriptors) { if (!pd.IsLocalizable) { localizable = TriState.No; break; } } } return (localizable == TriState.Yes); } } ////// Gets a value /// indicating whether this property should be localized, as /// specified in the ///. /// /// /// public override bool IsReadOnly { get { if (readOnly == TriState.Unknown) { readOnly = TriState.No; foreach (PropertyDescriptor pd in descriptors) { if (pd.IsReadOnly) { readOnly = TriState.Yes; break; } } } return (readOnly == TriState.Yes); } } ////// When overridden in /// a derived class, gets a value /// indicating whether this property is read-only. /// ////// /// public override Type PropertyType { get { return descriptors[0].PropertyType; } } public PropertyDescriptor this[int index] { get { return descriptors[index]; } } ////// When overridden in a derived class, /// gets the type of the property. /// ////// /// public override bool CanResetValue(object component) { Debug.Assert(component is Array, "MergePropertyDescriptor::CanResetValue called with non-array value"); if (canReset == TriState.Unknown) { canReset = TriState.Yes; Array a = (Array)component; for (int i = 0; i < descriptors.Length; i++) { if (!descriptors[i].CanResetValue(GetPropertyOwnerForComponent(a, i))) { canReset = TriState.No; break; } } } return (canReset == TriState.Yes); } ////// When overridden in a derived class, indicates whether /// resetting the ///will change the value of the /// . /// /// This method attempts to copy the given value so unique values are /// always passed to each object. If the object cannot be copied it /// will be returned. /// private object CopyValue(object value) { // null is always OK if (value == null) { return value; } Type type = value.GetType(); // value types are always copies if (type.IsValueType) { return value; } object clonedValue = null; // ICloneable is the next easiest thing ICloneable clone = value as ICloneable; if (clone != null) { clonedValue = clone.Clone(); } // Next, access the type converter if (clonedValue == null) { TypeConverter converter = TypeDescriptor.GetConverter(value); if (converter.CanConvertTo(typeof(InstanceDescriptor))) { // Instance descriptors provide full fidelity unless // they are marked as incomplete. InstanceDescriptor desc = (InstanceDescriptor)converter.ConvertTo(null, CultureInfo.InvariantCulture, value, typeof(InstanceDescriptor)); if (desc != null && desc.IsComplete) { clonedValue = desc.Invoke(); } } // If that didn't work, try conversion to/from string if (clonedValue == null && converter.CanConvertTo(typeof(string)) && converter.CanConvertFrom(typeof(string))) { object stringRep = converter.ConvertToInvariantString(value); clonedValue = converter.ConvertFromInvariantString((string)stringRep); } } // How about serialization? if (clonedValue == null && type.IsSerializable) { BinaryFormatter f = new BinaryFormatter(); MemoryStream ms = new MemoryStream(); f.Serialize(ms, value); ms.Position = 0; clonedValue = f.Deserialize(ms); } if (clonedValue != null) { return clonedValue; } // we failed. This object's reference will be set on each property. return value; } ////// /// protected override AttributeCollection CreateAttributeCollection() { return new MergedAttributeCollection(this); } private object GetPropertyOwnerForComponent(Array a, int i) { object propertyOwner = a.GetValue(i); if (propertyOwner is ICustomTypeDescriptor) { propertyOwner = ((ICustomTypeDescriptor) propertyOwner).GetPropertyOwner(descriptors[i]); } return propertyOwner; } ////// Creates a collection of attributes using the /// array of attributes that you passed to the constructor. /// ////// /// public override object GetEditor(Type editorBaseType) { return descriptors[0].GetEditor(editorBaseType); } ////// Gets an editor of the specified type. /// ////// /// public override object GetValue(object component) { Debug.Assert(component is Array, "MergePropertyDescriptor::GetValue called with non-array value"); bool temp; return GetValue((Array)component, out temp); } public object GetValue(Array components, out bool allEqual) { allEqual = true; object obj = descriptors[0].GetValue(GetPropertyOwnerForComponent(components, 0)); if (obj is ICollection) { if (collection == null) { collection = new MultiMergeCollection((ICollection)obj); } else if (collection.Locked) { return collection; } else { collection.SetItems((ICollection)obj); } } for (int i = 1; i < descriptors.Length; i++) { object objCur = descriptors[i].GetValue(GetPropertyOwnerForComponent(components, i)); if (collection != null) { if (!collection.MergeCollection((ICollection)objCur)){ allEqual = false; return null; } } else if ((obj == null && objCur == null) || (obj != null && obj.Equals(objCur))) { continue; } else { allEqual = false; return null; } } if (allEqual && collection != null && collection.Count == 0) { return null; } return (collection != null ? collection : obj); } internal object[] GetValues(Array components) { object[] values = new object[components.Length]; for (int i = 0; i < components.Length; i++) { values[i] = descriptors[i].GetValue(GetPropertyOwnerForComponent(components, i)); } return values; } ////// When overridden in a derived class, gets the current /// value /// of the /// property on a component. /// ////// /// public override void ResetValue(object component) { Debug.Assert(component is Array, "MergePropertyDescriptor::ResetValue called with non-array value"); Array a = (Array)component; for (int i = 0; i < descriptors.Length; i++) { descriptors[i].ResetValue(GetPropertyOwnerForComponent(a, i)); } } private void SetCollectionValues(Array a, IList listValue) { try { if (collection != null) { collection.Locked = true; } // now we have to copy the value into each property. object[] values = new object[listValue.Count]; listValue.CopyTo(values, 0); for (int i = 0; i < descriptors.Length; i++) { IList propList = descriptors[i].GetValue(GetPropertyOwnerForComponent(a, i)) as IList; if (propList == null) { continue; } propList.Clear(); foreach (object val in values) { propList.Add(val); } } } finally { if (collection != null) { collection.Locked = false; } } } ////// When overridden in a derived class, resets the /// value /// for this property /// of the component. /// ////// /// public override void SetValue(object component, object value) { Debug.Assert(component is Array, "MergePropertyDescriptor::SetValue called with non-array value"); Array a = (Array)component; if (value is IList && typeof(IList).IsAssignableFrom(PropertyType)) { SetCollectionValues(a, (IList)value); } else { for (int i = 0; i < descriptors.Length; i++) { object clonedValue = CopyValue(value); descriptors[i].SetValue(GetPropertyOwnerForComponent(a, i), clonedValue); } } } ////// When overridden in a derived class, sets the value of /// the component to a different value. /// ////// /// public override bool ShouldSerializeValue(object component) { Debug.Assert(component is Array, "MergePropertyDescriptor::ShouldSerializeValue called with non-array value"); Array a = (Array)component; for (int i = 0; i < descriptors.Length; i++) { if (!descriptors[i].ShouldSerializeValue(GetPropertyOwnerForComponent(a, i))) { return false; } } return true; } private class MultiMergeCollection : ICollection { private object[] items; private bool locked; public MultiMergeCollection(ICollection original) { SetItems(original); } ////// When overridden in a derived class, indicates whether the /// value of /// this property needs to be persisted. /// ////// /// Retrieves the number of items. /// public int Count { get { if (items != null) { return items.Length; } else { return 0; } } } ////// /// Prevents the contents of the collection from being re-initialized; /// public bool Locked { get { return locked; } set { this.locked = value; } } object ICollection.SyncRoot { get { return this; } } bool ICollection.IsSynchronized { get { return false; } } public void CopyTo(Array array, int index) { if (items == null) return; Array.Copy(items, 0, array, index, items.Length); } public IEnumerator GetEnumerator(){ if (items != null) { return items.GetEnumerator(); } else { return new object[0].GetEnumerator(); } } ////// /// Ensures that the new collection equals the exisitng one. /// Otherwise, it wipes out the contents of the new collection. /// public bool MergeCollection(ICollection newCollection) { if (locked) { return true; } if (items.Length != newCollection.Count) { items = new object[0]; return false; } object[] newItems = new object[newCollection.Count]; newCollection.CopyTo(newItems, 0); for (int i = 0;i < newItems.Length; i++) { if (((newItems[i] == null) != (items[i] == null)) || (items[i] != null && !items[i].Equals(newItems[i]))){ items = new object[0]; return false; } } return true; } public void SetItems(ICollection collection) { if (locked) { return; } items = new object[collection.Count]; collection.CopyTo(items, 0); } } private class MergedAttributeCollection : AttributeCollection { private MergePropertyDescriptor owner; private AttributeCollection[] attributeCollections = null; private IDictionary foundAttributes = null; public MergedAttributeCollection(MergePropertyDescriptor owner) : base((Attribute[])null) { this.owner = owner; } public override Attribute this[Type attributeType] { get { return GetCommonAttribute(attributeType); } } #if false private void FullMerge() { Attribute[][] collections = new Attribute[owner.descriptors.Length][]; for (int i = 0; i < owner.descriptors.Length; i++) { AttributeCollection attrCollection = owner.descriptors[i].Attributes; collections[i] = new Attribute[attrCollection.Count]; attrCollection.CopyTo(collections[i], 0); Array.Sort(collections[i], GridEntry.AttributeTypeSorter); } ArrayList mergedList = new ArrayList(); // merge the sorted lists -- note that lists aren't fully sorted just by // Attribute.TypeId // int[] posArray = new int[collections.Length]; for (int i = 0; i < collections[0].Length; i++) { Attribute pivotAttr = collections[0][i]; bool match = true; for (int j = 1; j < collections.Length; j++) { if (posArray[j] >= collections[j].Length) { match = false; break; } // check to see if we're on a match // if (pivotAttr.Equals(collections[j][posArray[j]])) { posArray[j] += 1; continue; } int jPos = posArray[j]; Attribute jAttr = collections[j][jPos]; match = false; // if we aren't on a match, check all the items until we're past // where the matching item would be while (GridEntry.AttributeTypeSorter.Compare(jAttr, pivotAttr) <= 0) { // got a match! if (pivotAttr.Equals(jAttr)) { posArray[j] = jPos + 1; match = true; break; } // try again jPos++; if (jPos < collections[j].Length) { jAttr = collections[j][jPos]; } else { break; } } // if we got here, there is no match, quit for this guy if (!match) { posArray[j] = jPos; break; } } // do we have a match? if (match) { mergedList.Add(pivotAttr); } } // create our merged array Attribute[] mergedAttrs = new Attribute[mergedList.Count]; mergedList.CopyTo(mergedAttrs, 0); } #endif private Attribute GetCommonAttribute(Type attributeType) { if (attributeCollections == null) { attributeCollections = new AttributeCollection[owner.descriptors.Length]; for (int i = 0; i < owner.descriptors.Length; i++) { attributeCollections[i] = owner.descriptors[i].Attributes; } } if (attributeCollections.Length == 0) { return GetDefaultAttribute(attributeType); } Attribute value; if (foundAttributes != null) { value = foundAttributes[attributeType] as Attribute; if (value != null) { return value; } } value = attributeCollections[0][attributeType]; if (value == null) { return null; } for (int i = 1; i < attributeCollections.Length; i++) { Attribute newValue = attributeCollections[i][attributeType]; if (!value.Equals(newValue)) { value = GetDefaultAttribute(attributeType); break; } } if (foundAttributes == null) { foundAttributes = new Hashtable(); } foundAttributes[attributeType] = value; return value; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.Windows.Forms.PropertyGridInternal { using System.Runtime.Serialization.Formatters; using System.Runtime.Serialization.Formatters.Binary; using System.ComponentModel; using System.Diagnostics; using System; using System.IO; using System.Collections; using System.Globalization; using System.Reflection; using System.ComponentModel.Design; using System.ComponentModel.Design.Serialization; using System.Windows.Forms; using System.Drawing; using Microsoft.Win32; internal class MergePropertyDescriptor : PropertyDescriptor { private PropertyDescriptor[] descriptors; private enum TriState { Unknown, Yes, No } private TriState localizable = TriState.Unknown; private TriState readOnly = TriState.Unknown; private TriState canReset = TriState.Unknown; private MultiMergeCollection collection; public MergePropertyDescriptor(PropertyDescriptor[] descriptors) : base(descriptors[0].Name, null) { this.descriptors = descriptors; } ////// /// public override Type ComponentType { get { return descriptors[0].ComponentType; } } ////// When overridden in a derived class, gets the type of the /// component this property /// is bound to. /// ////// /// public override TypeConverter Converter { get { return descriptors[0].Converter; } } public override string DisplayName { get { return descriptors[0].DisplayName; } } ////// Gets the type converter for this property. /// ////// /// public override bool IsLocalizable { get { if (localizable == TriState.Unknown) { localizable = TriState.Yes; foreach (PropertyDescriptor pd in descriptors) { if (!pd.IsLocalizable) { localizable = TriState.No; break; } } } return (localizable == TriState.Yes); } } ////// Gets a value /// indicating whether this property should be localized, as /// specified in the ///. /// /// /// public override bool IsReadOnly { get { if (readOnly == TriState.Unknown) { readOnly = TriState.No; foreach (PropertyDescriptor pd in descriptors) { if (pd.IsReadOnly) { readOnly = TriState.Yes; break; } } } return (readOnly == TriState.Yes); } } ////// When overridden in /// a derived class, gets a value /// indicating whether this property is read-only. /// ////// /// public override Type PropertyType { get { return descriptors[0].PropertyType; } } public PropertyDescriptor this[int index] { get { return descriptors[index]; } } ////// When overridden in a derived class, /// gets the type of the property. /// ////// /// public override bool CanResetValue(object component) { Debug.Assert(component is Array, "MergePropertyDescriptor::CanResetValue called with non-array value"); if (canReset == TriState.Unknown) { canReset = TriState.Yes; Array a = (Array)component; for (int i = 0; i < descriptors.Length; i++) { if (!descriptors[i].CanResetValue(GetPropertyOwnerForComponent(a, i))) { canReset = TriState.No; break; } } } return (canReset == TriState.Yes); } ////// When overridden in a derived class, indicates whether /// resetting the ///will change the value of the /// . /// /// This method attempts to copy the given value so unique values are /// always passed to each object. If the object cannot be copied it /// will be returned. /// private object CopyValue(object value) { // null is always OK if (value == null) { return value; } Type type = value.GetType(); // value types are always copies if (type.IsValueType) { return value; } object clonedValue = null; // ICloneable is the next easiest thing ICloneable clone = value as ICloneable; if (clone != null) { clonedValue = clone.Clone(); } // Next, access the type converter if (clonedValue == null) { TypeConverter converter = TypeDescriptor.GetConverter(value); if (converter.CanConvertTo(typeof(InstanceDescriptor))) { // Instance descriptors provide full fidelity unless // they are marked as incomplete. InstanceDescriptor desc = (InstanceDescriptor)converter.ConvertTo(null, CultureInfo.InvariantCulture, value, typeof(InstanceDescriptor)); if (desc != null && desc.IsComplete) { clonedValue = desc.Invoke(); } } // If that didn't work, try conversion to/from string if (clonedValue == null && converter.CanConvertTo(typeof(string)) && converter.CanConvertFrom(typeof(string))) { object stringRep = converter.ConvertToInvariantString(value); clonedValue = converter.ConvertFromInvariantString((string)stringRep); } } // How about serialization? if (clonedValue == null && type.IsSerializable) { BinaryFormatter f = new BinaryFormatter(); MemoryStream ms = new MemoryStream(); f.Serialize(ms, value); ms.Position = 0; clonedValue = f.Deserialize(ms); } if (clonedValue != null) { return clonedValue; } // we failed. This object's reference will be set on each property. return value; } ////// /// protected override AttributeCollection CreateAttributeCollection() { return new MergedAttributeCollection(this); } private object GetPropertyOwnerForComponent(Array a, int i) { object propertyOwner = a.GetValue(i); if (propertyOwner is ICustomTypeDescriptor) { propertyOwner = ((ICustomTypeDescriptor) propertyOwner).GetPropertyOwner(descriptors[i]); } return propertyOwner; } ////// Creates a collection of attributes using the /// array of attributes that you passed to the constructor. /// ////// /// public override object GetEditor(Type editorBaseType) { return descriptors[0].GetEditor(editorBaseType); } ////// Gets an editor of the specified type. /// ////// /// public override object GetValue(object component) { Debug.Assert(component is Array, "MergePropertyDescriptor::GetValue called with non-array value"); bool temp; return GetValue((Array)component, out temp); } public object GetValue(Array components, out bool allEqual) { allEqual = true; object obj = descriptors[0].GetValue(GetPropertyOwnerForComponent(components, 0)); if (obj is ICollection) { if (collection == null) { collection = new MultiMergeCollection((ICollection)obj); } else if (collection.Locked) { return collection; } else { collection.SetItems((ICollection)obj); } } for (int i = 1; i < descriptors.Length; i++) { object objCur = descriptors[i].GetValue(GetPropertyOwnerForComponent(components, i)); if (collection != null) { if (!collection.MergeCollection((ICollection)objCur)){ allEqual = false; return null; } } else if ((obj == null && objCur == null) || (obj != null && obj.Equals(objCur))) { continue; } else { allEqual = false; return null; } } if (allEqual && collection != null && collection.Count == 0) { return null; } return (collection != null ? collection : obj); } internal object[] GetValues(Array components) { object[] values = new object[components.Length]; for (int i = 0; i < components.Length; i++) { values[i] = descriptors[i].GetValue(GetPropertyOwnerForComponent(components, i)); } return values; } ////// When overridden in a derived class, gets the current /// value /// of the /// property on a component. /// ////// /// public override void ResetValue(object component) { Debug.Assert(component is Array, "MergePropertyDescriptor::ResetValue called with non-array value"); Array a = (Array)component; for (int i = 0; i < descriptors.Length; i++) { descriptors[i].ResetValue(GetPropertyOwnerForComponent(a, i)); } } private void SetCollectionValues(Array a, IList listValue) { try { if (collection != null) { collection.Locked = true; } // now we have to copy the value into each property. object[] values = new object[listValue.Count]; listValue.CopyTo(values, 0); for (int i = 0; i < descriptors.Length; i++) { IList propList = descriptors[i].GetValue(GetPropertyOwnerForComponent(a, i)) as IList; if (propList == null) { continue; } propList.Clear(); foreach (object val in values) { propList.Add(val); } } } finally { if (collection != null) { collection.Locked = false; } } } ////// When overridden in a derived class, resets the /// value /// for this property /// of the component. /// ////// /// public override void SetValue(object component, object value) { Debug.Assert(component is Array, "MergePropertyDescriptor::SetValue called with non-array value"); Array a = (Array)component; if (value is IList && typeof(IList).IsAssignableFrom(PropertyType)) { SetCollectionValues(a, (IList)value); } else { for (int i = 0; i < descriptors.Length; i++) { object clonedValue = CopyValue(value); descriptors[i].SetValue(GetPropertyOwnerForComponent(a, i), clonedValue); } } } ////// When overridden in a derived class, sets the value of /// the component to a different value. /// ////// /// public override bool ShouldSerializeValue(object component) { Debug.Assert(component is Array, "MergePropertyDescriptor::ShouldSerializeValue called with non-array value"); Array a = (Array)component; for (int i = 0; i < descriptors.Length; i++) { if (!descriptors[i].ShouldSerializeValue(GetPropertyOwnerForComponent(a, i))) { return false; } } return true; } private class MultiMergeCollection : ICollection { private object[] items; private bool locked; public MultiMergeCollection(ICollection original) { SetItems(original); } ////// When overridden in a derived class, indicates whether the /// value of /// this property needs to be persisted. /// ////// /// Retrieves the number of items. /// public int Count { get { if (items != null) { return items.Length; } else { return 0; } } } ////// /// Prevents the contents of the collection from being re-initialized; /// public bool Locked { get { return locked; } set { this.locked = value; } } object ICollection.SyncRoot { get { return this; } } bool ICollection.IsSynchronized { get { return false; } } public void CopyTo(Array array, int index) { if (items == null) return; Array.Copy(items, 0, array, index, items.Length); } public IEnumerator GetEnumerator(){ if (items != null) { return items.GetEnumerator(); } else { return new object[0].GetEnumerator(); } } ////// /// Ensures that the new collection equals the exisitng one. /// Otherwise, it wipes out the contents of the new collection. /// public bool MergeCollection(ICollection newCollection) { if (locked) { return true; } if (items.Length != newCollection.Count) { items = new object[0]; return false; } object[] newItems = new object[newCollection.Count]; newCollection.CopyTo(newItems, 0); for (int i = 0;i < newItems.Length; i++) { if (((newItems[i] == null) != (items[i] == null)) || (items[i] != null && !items[i].Equals(newItems[i]))){ items = new object[0]; return false; } } return true; } public void SetItems(ICollection collection) { if (locked) { return; } items = new object[collection.Count]; collection.CopyTo(items, 0); } } private class MergedAttributeCollection : AttributeCollection { private MergePropertyDescriptor owner; private AttributeCollection[] attributeCollections = null; private IDictionary foundAttributes = null; public MergedAttributeCollection(MergePropertyDescriptor owner) : base((Attribute[])null) { this.owner = owner; } public override Attribute this[Type attributeType] { get { return GetCommonAttribute(attributeType); } } #if false private void FullMerge() { Attribute[][] collections = new Attribute[owner.descriptors.Length][]; for (int i = 0; i < owner.descriptors.Length; i++) { AttributeCollection attrCollection = owner.descriptors[i].Attributes; collections[i] = new Attribute[attrCollection.Count]; attrCollection.CopyTo(collections[i], 0); Array.Sort(collections[i], GridEntry.AttributeTypeSorter); } ArrayList mergedList = new ArrayList(); // merge the sorted lists -- note that lists aren't fully sorted just by // Attribute.TypeId // int[] posArray = new int[collections.Length]; for (int i = 0; i < collections[0].Length; i++) { Attribute pivotAttr = collections[0][i]; bool match = true; for (int j = 1; j < collections.Length; j++) { if (posArray[j] >= collections[j].Length) { match = false; break; } // check to see if we're on a match // if (pivotAttr.Equals(collections[j][posArray[j]])) { posArray[j] += 1; continue; } int jPos = posArray[j]; Attribute jAttr = collections[j][jPos]; match = false; // if we aren't on a match, check all the items until we're past // where the matching item would be while (GridEntry.AttributeTypeSorter.Compare(jAttr, pivotAttr) <= 0) { // got a match! if (pivotAttr.Equals(jAttr)) { posArray[j] = jPos + 1; match = true; break; } // try again jPos++; if (jPos < collections[j].Length) { jAttr = collections[j][jPos]; } else { break; } } // if we got here, there is no match, quit for this guy if (!match) { posArray[j] = jPos; break; } } // do we have a match? if (match) { mergedList.Add(pivotAttr); } } // create our merged array Attribute[] mergedAttrs = new Attribute[mergedList.Count]; mergedList.CopyTo(mergedAttrs, 0); } #endif private Attribute GetCommonAttribute(Type attributeType) { if (attributeCollections == null) { attributeCollections = new AttributeCollection[owner.descriptors.Length]; for (int i = 0; i < owner.descriptors.Length; i++) { attributeCollections[i] = owner.descriptors[i].Attributes; } } if (attributeCollections.Length == 0) { return GetDefaultAttribute(attributeType); } Attribute value; if (foundAttributes != null) { value = foundAttributes[attributeType] as Attribute; if (value != null) { return value; } } value = attributeCollections[0][attributeType]; if (value == null) { return null; } for (int i = 1; i < attributeCollections.Length; i++) { Attribute newValue = attributeCollections[i][attributeType]; if (!value.Equals(newValue)) { value = GetDefaultAttribute(attributeType); break; } } if (foundAttributes == null) { foundAttributes = new Hashtable(); } foundAttributes[attributeType] = value; return value; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CancelEventArgs.cs
- TemplateBindingExtension.cs
- ServiceThrottlingElement.cs
- WorkflowElementDialog.cs
- ValidationPropertyAttribute.cs
- CodeTypeReferenceExpression.cs
- HashAlgorithm.cs
- ContextBase.cs
- ExecutedRoutedEventArgs.cs
- Internal.cs
- GridViewCancelEditEventArgs.cs
- EditorZone.cs
- XmlHelper.cs
- SecurityChannelFaultConverter.cs
- FrameworkPropertyMetadata.cs
- XmlEncodedRawTextWriter.cs
- WebUtil.cs
- XmlComment.cs
- SecureUICommand.cs
- ToggleProviderWrapper.cs
- RSAOAEPKeyExchangeFormatter.cs
- CollectionViewSource.cs
- NativeCompoundFileAPIs.cs
- GPPOINT.cs
- Identity.cs
- DrawToolTipEventArgs.cs
- StringValidator.cs
- SortedDictionary.cs
- TextDpi.cs
- Delegate.cs
- ScalarOps.cs
- EventBuilder.cs
- LineGeometry.cs
- BitSet.cs
- EntityClientCacheKey.cs
- RegexInterpreter.cs
- WorkflowServiceNamespace.cs
- ClientRuntimeConfig.cs
- BulletChrome.cs
- Speller.cs
- ThreadExceptionDialog.cs
- InputLanguageCollection.cs
- DBCSCodePageEncoding.cs
- XmlTextReader.cs
- TopClause.cs
- SettingsAttributeDictionary.cs
- SiteMapSection.cs
- BigInt.cs
- Expr.cs
- TaskHelper.cs
- ItemChangedEventArgs.cs
- OrderablePartitioner.cs
- WebPartDisplayMode.cs
- StringStorage.cs
- DetailsViewUpdateEventArgs.cs
- BinaryNode.cs
- DataGridViewRowContextMenuStripNeededEventArgs.cs
- AsyncOperation.cs
- EntityDesignerBuildProvider.cs
- ApplicationSecurityManager.cs
- DocumentAutomationPeer.cs
- ProcessProtocolHandler.cs
- RequestCache.cs
- _NTAuthentication.cs
- NativeMethods.cs
- XPathAncestorIterator.cs
- SolidBrush.cs
- MediaPlayerState.cs
- VarRemapper.cs
- SQLStringStorage.cs
- InvokePattern.cs
- Rotation3DKeyFrameCollection.cs
- DataGridViewCellMouseEventArgs.cs
- SocketPermission.cs
- ViewPort3D.cs
- CodeMemberProperty.cs
- ListBoxItem.cs
- StringAttributeCollection.cs
- CssTextWriter.cs
- DataSourceExpressionCollection.cs
- XamlWriter.cs
- xmlformatgeneratorstatics.cs
- ArrayConverter.cs
- WSHttpBindingBaseElement.cs
- WebPartTransformerCollection.cs
- WebPartHelpVerb.cs
- SspiWrapper.cs
- XmlSchemaInferenceException.cs
- HandlerBase.cs
- BindingBase.cs
- DesignColumnCollection.cs
- PropertyConverter.cs
- XmlCompatibilityReader.cs
- DateTimeOffset.cs
- ScrollableControl.cs
- WorkItem.cs
- SqlProviderServices.cs
- OutputCacheProfile.cs
- Animatable.cs
- TableColumn.cs