Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / PropertyGridInternal / MergePropertyDescriptor.cs / 1305376 / 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;
}
///
///
///
/// When overridden in a derived class, gets the type of the
/// component this property
/// is bound to.
///
///
public override Type ComponentType {
get {
return descriptors[0].ComponentType;
}
}
///
///
///
/// Gets the type converter for this property.
///
///
public override TypeConverter Converter {
get {
return descriptors[0].Converter;
}
}
public override string DisplayName {
get {
return descriptors[0].DisplayName;
}
}
///
///
///
/// Gets a value
/// indicating whether this property should be localized, as
/// specified in the .
///
///
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);
}
}
///
///
///
/// When overridden in
/// a derived class, gets a value
/// indicating whether this property is read-only.
///
///
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 the type of the property.
///
///
public override Type PropertyType {
get {
return descriptors[0].PropertyType;
}
}
public PropertyDescriptor this[int index] {
get {
return descriptors[index];
}
}
///
///
///
/// When overridden in a derived class, indicates whether
/// resetting the will change the value of the
/// .
///
///
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);
}
///
/// 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;
}
///
///
///
/// Creates a collection of attributes using the
/// array of attributes that you passed to the constructor.
///
///
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;
}
///
///
///
/// Gets an editor of the specified type.
///
///
public override object GetEditor(Type editorBaseType) {
return descriptors[0].GetEditor(editorBaseType);
}
///
///
///
/// When overridden in a derived class, gets the current
/// value
/// of the
/// property on a component.
///
///
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, resets the
/// value
/// for this property
/// of the 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, sets the value of
/// the component to a different value.
///
///
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, indicates whether the
/// value of
/// this property needs to be persisted.
///
///
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);
}
///
///
/// 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;
}
///
///
///
/// When overridden in a derived class, gets the type of the
/// component this property
/// is bound to.
///
///
public override Type ComponentType {
get {
return descriptors[0].ComponentType;
}
}
///
///
///
/// Gets the type converter for this property.
///
///
public override TypeConverter Converter {
get {
return descriptors[0].Converter;
}
}
public override string DisplayName {
get {
return descriptors[0].DisplayName;
}
}
///
///
///
/// Gets a value
/// indicating whether this property should be localized, as
/// specified in the .
///
///
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);
}
}
///
///
///
/// When overridden in
/// a derived class, gets a value
/// indicating whether this property is read-only.
///
///
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 the type of the property.
///
///
public override Type PropertyType {
get {
return descriptors[0].PropertyType;
}
}
public PropertyDescriptor this[int index] {
get {
return descriptors[index];
}
}
///
///
///
/// When overridden in a derived class, indicates whether
/// resetting the will change the value of the
/// .
///
///
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);
}
///
/// 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;
}
///
///
///
/// Creates a collection of attributes using the
/// array of attributes that you passed to the constructor.
///
///
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;
}
///
///
///
/// Gets an editor of the specified type.
///
///
public override object GetEditor(Type editorBaseType) {
return descriptors[0].GetEditor(editorBaseType);
}
///
///
///
/// When overridden in a derived class, gets the current
/// value
/// of the
/// property on a component.
///
///
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, resets the
/// value
/// for this property
/// of the 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, sets the value of
/// the component to a different value.
///
///
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, indicates whether the
/// value of
/// this property needs to be persisted.
///
///
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);
}
///
///
/// 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
- InkSerializer.cs
- PortCache.cs
- TypeContext.cs
- SecurityTokenProvider.cs
- SmtpDigestAuthenticationModule.cs
- ImportException.cs
- DataSourceControl.cs
- QueryableDataSourceHelper.cs
- SystemInformation.cs
- RectAnimationClockResource.cs
- CommentGlyph.cs
- ProfilePropertySettings.cs
- ClientTargetSection.cs
- CheckBoxStandardAdapter.cs
- ProvidePropertyAttribute.cs
- ExpressionHelper.cs
- EmptyCollection.cs
- XmlStreamStore.cs
- PresentationTraceSources.cs
- EventBuilder.cs
- ParallelActivityDesigner.cs
- WriteFileContext.cs
- MatrixValueSerializer.cs
- XmlElement.cs
- SortDescription.cs
- ArrangedElement.cs
- SmtpClient.cs
- CachedBitmap.cs
- SimpleHandlerBuildProvider.cs
- ColorTranslator.cs
- PointLight.cs
- RoleServiceManager.cs
- PowerStatus.cs
- TransformedBitmap.cs
- SoapParser.cs
- StrongNameUtility.cs
- WebBrowserHelper.cs
- Nodes.cs
- Translator.cs
- RelatedCurrencyManager.cs
- CodeConstructor.cs
- CompoundFileDeflateTransform.cs
- FileIOPermission.cs
- AnnotationHighlightLayer.cs
- PenThreadWorker.cs
- ConnectionStringSettings.cs
- ClientConvert.cs
- ClientRuntimeConfig.cs
- XhtmlBasicPhoneCallAdapter.cs
- Triplet.cs
- DataGridViewSelectedCellCollection.cs
- GroupByExpressionRewriter.cs
- OTFRasterizer.cs
- LocalBuilder.cs
- TextDataBindingHandler.cs
- SqlMultiplexer.cs
- MdiWindowListItemConverter.cs
- PaperSize.cs
- CustomAttributeBuilder.cs
- SoapAttributeOverrides.cs
- OracleConnection.cs
- XPathBinder.cs
- ImportCatalogPart.cs
- ListManagerBindingsCollection.cs
- EntitySet.cs
- BitmapDownload.cs
- WebPartConnectionsEventArgs.cs
- QueryExtender.cs
- TextProviderWrapper.cs
- TypeExtensions.cs
- DataGridTablesFactory.cs
- SHA1Managed.cs
- Atom10FormatterFactory.cs
- IsolatedStorageException.cs
- AuthenticationSection.cs
- SQLConvert.cs
- UpDownBase.cs
- EndEvent.cs
- ClientCultureInfo.cs
- EntityStoreSchemaFilterEntry.cs
- WebPartDeleteVerb.cs
- PerformanceCounterPermissionAttribute.cs
- DataGridItemAttachedStorage.cs
- NetStream.cs
- Pkcs9Attribute.cs
- ErrorTableItemStyle.cs
- Variable.cs
- SqlClientWrapperSmiStreamChars.cs
- TraceXPathNavigator.cs
- CheckBoxBaseAdapter.cs
- DoWhileDesigner.xaml.cs
- WSTrustFeb2005.cs
- CompoundFileDeflateTransform.cs
- SmtpTransport.cs
- QueryStatement.cs
- ContextQuery.cs
- UserNamePasswordValidator.cs
- LocatorPartList.cs
- SmiRequestExecutor.cs
- Int64.cs