Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / Model / ModelItemDictionaryImpl.cs / 1305376 / ModelItemDictionaryImpl.cs
//---------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------- namespace System.Activities.Presentation.Model { using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Windows; using System.Windows.Markup; using System.Activities.Presentation.Services; using System.Linq; using System.Reflection; using System.Runtime; using System.Diagnostics.CodeAnalysis; using System.Globalization; class ModelItemDictionaryImpl : ModelItemDictionary, IModelTreeItem, ICustomTypeDescriptor { ModelProperty contentProperty; DictionaryWrapper instance; Type itemType; DictionarymodelItems; Dictionary modelPropertyStore; ModelTreeManager modelTreeManager; ModelProperty nameProperty; List parents; ModelPropertyCollectionImpl properties; List sources; List subTreeNodesThatNeedBackLinkPatching; DependencyObject view; public ModelItemDictionaryImpl(ModelTreeManager modelTreeManager, Type itemType, Object instance, ModelItem parent) { Fx.Assert(modelTreeManager != null, "modelTreeManager cannot be null"); Fx.Assert(itemType != null, "item type cannot be null"); Fx.Assert(instance != null, "instance cannot be null"); this.itemType = itemType; this.instance = new DictionaryWrapper(instance); this.modelTreeManager = modelTreeManager; this.parents = new List (1); this.sources = new List (1); if (parent != null) { this.parents.Add(parent); } this.modelPropertyStore = new Dictionary (); this.subTreeNodesThatNeedBackLinkPatching = new List (); this.modelItems = new Dictionary (); UpdateInstance(); } public override event NotifyCollectionChangedEventHandler CollectionChanged; public override event PropertyChangedEventHandler PropertyChanged; public override int Count { get { return this.instance.Count; } } public override bool IsReadOnly { get { return this.instance.IsReadOnly; } } public override ICollection Keys { get { return this.modelItems.Keys; } } public override ICollection Values { get { return this.modelItems.Values; } } public override AttributeCollection Attributes { get { Fx.Assert(null != this.itemType, "ItemType cannot be null!"); return TypeDescriptor.GetAttributes(this.itemType); } } public override ModelProperty Content { get { if (this.contentProperty == null) { Fx.Assert(this.instance != null, "instance cannot be null"); ContentPropertyAttribute contentAttribute = TypeDescriptor.GetAttributes(this.instance.Value)[typeof(ContentPropertyAttribute)] as ContentPropertyAttribute; if (contentAttribute != null && !String.IsNullOrEmpty(contentAttribute.Name)) { this.contentProperty = this.Properties.Find(contentAttribute.Name); } } return contentProperty; } } public override Type ItemType { get { return this.itemType; } } public override string Name { get { string name = null; if ((this.NameProperty != null) && (this.NameProperty.Value != null)) { name = (string)this.NameProperty.Value.GetCurrentValue(); } return name; } set { if (null != this.NameProperty) { this.NameProperty.SetValue(value); } } } public override ModelItem Parent { get { return (this.Parents.Count() > 0) ? this.Parents.First() : null; } } public override ModelItem Root { get { return this.modelTreeManager.Root; } } public override ModelPropertyCollection Properties { get { if (this.properties == null) { this.properties = new ModelPropertyCollectionImpl(this); } return this.properties; } } public override ModelProperty Source { get { return (this.sources.Count > 0) ? this.sources.First() : null; } } public override DependencyObject View { get { return this.view; } } public ModelItem ModelItem { get { return this; } } public Dictionary ModelPropertyStore { get { return this.modelPropertyStore; } } public ModelTreeManager ModelTreeManager { get { return this.modelTreeManager; } } public override IEnumerable Parents { get { return this.parents.Concat( from source in this.sources select source.Parent); } } public override IEnumerable Sources { get { return this.sources; } } protected ModelProperty NameProperty { get { if (this.nameProperty == null) { Fx.Assert(this.instance != null, "instance cannot be null"); RuntimeNamePropertyAttribute runtimeNamePropertyAttribute = TypeDescriptor.GetAttributes(this.instance.Value)[typeof(RuntimeNamePropertyAttribute)] as RuntimeNamePropertyAttribute; if (runtimeNamePropertyAttribute != null && !String.IsNullOrEmpty(runtimeNamePropertyAttribute.Name)) { this.nameProperty = this.Properties.Find(runtimeNamePropertyAttribute.Name); } else { this.nameProperty = this.Properties.FirstOrDefault (p => (0 == string.Compare(p.Name, "Name", StringComparison.OrdinalIgnoreCase))); } } return nameProperty; } } public override ModelItem this[ModelItem key] { get { if (null == key || null == key.GetCurrentValue()) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } ModelItem value; if (!this.modelItems.TryGetValue(key, out value)) { throw FxTrace.Exception.AsError( new KeyNotFoundException(key.GetCurrentValue().ToString())); } return value; } set { if (null == key || null == key.GetCurrentValue()) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } if (this.instance.IsReadOnly) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR.CollectionIsReadOnly)); } ModelItem oldValue = null; if (this.modelItems.TryGetValue(key, out oldValue)) { this.modelTreeManager.DictionaryEdit(this, key, value, oldValue); } else { this.modelTreeManager.DictionaryAdd(this, key, value); } } } public override ModelItem this[object key] { get { if (null == key) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } ModelItem keyItem = this.KeyAsModelItem(key, false); if (null == keyItem) { throw FxTrace.Exception.AsError( new KeyNotFoundException(key.ToString())); } return this[keyItem]; } set { if (null == key) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } if (this.instance.IsReadOnly) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR.CollectionIsReadOnly)); } ModelItem keyItem = this.KeyAsModelItem(key, true); this[keyItem] = value; } } public override void Add(ModelItem key, ModelItem value) { if (null == key) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } if (this.instance.IsReadOnly) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR.CollectionIsReadOnly)); } this.modelTreeManager.DictionaryAdd(this, key, value); } public override ModelItem Add(object key, object value) { if (null == key) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } if (this.instance.IsReadOnly) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CollectionIsReadOnly)); } ModelItem keyModelItem = key as ModelItem ?? this.WrapObject(key); ModelItem valueModelItem = value as ModelItem ?? this.WrapObject(value); this.Add(keyModelItem, valueModelItem); return valueModelItem; } public override void Clear() { this.modelTreeManager.DictionaryClear(this); } public override bool ContainsKey(ModelItem key) { if (null == key) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } return this.modelItems.Keys.Contains (key); } public override bool ContainsKey(object key) { if (null == key) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } if (typeof(ModelItem).IsAssignableFrom(key.GetType())) { return this.ContainsKey(key as ModelItem); } return null != this.modelItems.Keys.SingleOrDefault (p => object.Equals(p.GetCurrentValue(), key)); } public override IEnumerator > GetEnumerator() { return this.modelItems.GetEnumerator(); } public override bool Remove(ModelItem key) { if (null == key) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } this.modelTreeManager.DictionaryRemove(this, key); return true; } public override bool Remove(object key) { if (null == key) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } ModelItem keyItem = this.KeyAsModelItem(key, false); if (null != keyItem) { return this.Remove(keyItem); } return false; } public override bool TryGetValue(ModelItem key, out ModelItem value) { if (null == key) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } return this.modelItems.TryGetValue(key, out value); } public override bool TryGetValue(object key, out ModelItem value) { if (null == key) { throw FxTrace.Exception.AsError( new ArgumentNullException("key")); } ModelItem keyItem = this.KeyAsModelItem(key, false); if (null == keyItem) { value = null; return false; } return this.TryGetValue(keyItem, out value); } public override ModelEditingScope BeginEdit(string description) { return this.modelTreeManager.CreateEditingScope(description); } public override ModelEditingScope BeginEdit() { return this.BeginEdit(null); } public override object GetCurrentValue() { return this.instance.Value; } #region IModelTreeItem Members public void OnPropertyChanged(string propertyName) { if (null != this.PropertyChanged) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } void IModelTreeItem.SetParent(ModelItem dataModelItem) { if (!this.parents.Contains(dataModelItem)) { this.parents.Add(dataModelItem); } } void IModelTreeItem.SetSource(ModelProperty property) { if (!this.sources.Contains(property)) { // also check if the same parent.property is in the list as a different instance of oldModelProperty ModelProperty foundProperty = this.sources.Find((modelProperty) => modelProperty.Name.Equals(property.Name) && property.Parent == modelProperty.Parent); if (foundProperty == null) { this.sources.Add(property); } } } IList IModelTreeItem.SubNodesThatNeedBackLinkUpdate { get { return this.subTreeNodesThatNeedBackLinkPatching; } } public void SetCurrentView(DependencyObject view) { this.view = view; } #endregion void IModelTreeItem.RemoveParent(ModelItem oldParent) { if (this.parents.Contains(oldParent)) { this.parents.Remove(oldParent); } } void IModelTreeItem.RemoveSource(ModelProperty oldModelProperty) { if (this.sources.Contains(oldModelProperty)) { this.sources.Remove(oldModelProperty); } else { // also check if the same parent.property is in the list as a different instance of oldModelProperty ModelProperty foundProperty = this.sources.Find((modelProperty) => modelProperty.Name.Equals(oldModelProperty.Name) && modelProperty.Parent == oldModelProperty.Parent); if (foundProperty != null) { this.sources.Remove(foundProperty); } else { Fx.Assert("Trying to call RemoveSource() on modelItem that is not parented by oldModelProperty"); } } } internal void EditCore(ModelItem key, ModelItem value) { Fx.Assert(this.instance != null, "instance should not be null"); if (key.Parent != this) { ((IModelTreeItem)key).SetParent(this); } if (null != value && value.Parent != this) { ((IModelTreeItem)value).SetParent(this); } this.instance[key.GetCurrentValue()] = null != value ? value.GetCurrentValue() : null; ModelItem oldValue = this.modelItems[key]; this.modelItems[key] = value; if (null != this.CollectionChanged) { this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, new KeyValuePair (key, value), new KeyValuePair (key, oldValue))); } } internal void AddCore(ModelItem key, ModelItem value) { Fx.Assert(this.instance != null, "instance should not be null"); if (key.Parent != this) { ((IModelTreeItem)key).SetParent(this); } if (null != value && value.Parent != this) { ((IModelTreeItem)value).SetParent(this); } this.instance.Add(key.GetCurrentValue(), null != value ? value.GetCurrentValue() : null); this.modelItems.Add(key, value); if (null != this.CollectionChanged) { this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, new KeyValuePair (key, value))); } } internal void ClearCore() { Fx.Assert(this.instance != null, "instance should not be null"); IList removed = this.modelItems.ToList >(); this.instance.Clear(); this.modelItems.Clear(); if (null != this.CollectionChanged) { this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removed)); } } internal void RemoveCore(ModelItem key) { Fx.Assert(this.instance != null, "instance should not be null"); ModelItem value = this.modelItems[key]; this.modelItems.Remove(key); this.instance.Remove(key.GetCurrentValue()); if (null != this.CollectionChanged) { this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new KeyValuePair (key, value))); } } void UpdateInstance() { IEnumerator dictionaryEnumerator = this.instance.GetEnumerator(); while (dictionaryEnumerator.MoveNext()) { object current = dictionaryEnumerator.Current; ModelItem key = this.WrapObject(instance.GetKeyFromCurrent(current)); ModelItem value = this.WrapObject(instance.GetValueFromCurrent(current)); if (key != null) { this.modelItems.Add(key, value); } } } ModelItem WrapObject(object value) { return this.ModelTreeManager.WrapAsModelItem(this, value); } ModelItem KeyAsModelItem(object value, bool createNew) { ModelItem result = (value as ModelItem) ?? (ModelItem)this.modelItems.Keys.SingleOrDefault (p => object.Equals(p.GetCurrentValue(), value)); if (createNew && null == result) { result = WrapObject(value); } return result; } sealed class DictionaryWrapper { object instance; bool isDictionary = false; PropertyInfo isReadOnlyProperty; PropertyInfo countProperty; PropertyInfo indexingProperty; MethodInfo addMethod; MethodInfo removeMethod; MethodInfo clearMethod; MethodInfo getEnumeratorMethod; PropertyInfo keyProperty; PropertyInfo valueProperty; public DictionaryWrapper(object instance) { this.instance = instance; if (instance is IDictionary) { this.isDictionary = true; Type keyValuePairType = typeof(KeyValuePair
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XslVisitor.cs
- ArraySubsetEnumerator.cs
- BaseUriHelper.cs
- ProjectionPlanCompiler.cs
- DescendantOverDescendantQuery.cs
- DataTableMapping.cs
- SspiHelper.cs
- ToolboxItem.cs
- XmlQueryOutput.cs
- WebRequestModuleElement.cs
- CodeExpressionCollection.cs
- DataTableReader.cs
- EventBuilder.cs
- FocusWithinProperty.cs
- ShaderEffect.cs
- XsdDateTime.cs
- FacetValues.cs
- EventMappingSettings.cs
- SystemResourceKey.cs
- mongolianshape.cs
- DecimalAnimation.cs
- FragmentQuery.cs
- ADMembershipProvider.cs
- DataRecordObjectView.cs
- FormsIdentity.cs
- UserControlCodeDomTreeGenerator.cs
- TokenCreationParameter.cs
- ZipIOExtraFieldPaddingElement.cs
- SweepDirectionValidation.cs
- DataSourceSelectArguments.cs
- BufferedGraphicsManager.cs
- NumericExpr.cs
- SortedSetDebugView.cs
- GridViewCommandEventArgs.cs
- StandardCommands.cs
- TableDetailsCollection.cs
- Menu.cs
- SessionPageStatePersister.cs
- RuntimeConfig.cs
- TheQuery.cs
- ToolStripCollectionEditor.cs
- WebRequestModulesSection.cs
- ProbeMatchesCD1.cs
- AlignmentXValidation.cs
- ValidationManager.cs
- EmptyTextWriter.cs
- _RequestLifetimeSetter.cs
- XPathConvert.cs
- XmlSchemaAll.cs
- WindowsSolidBrush.cs
- ExpressionBuilderCollection.cs
- _HeaderInfoTable.cs
- BuildProvider.cs
- GestureRecognizer.cs
- ProcessThreadCollection.cs
- FieldAccessException.cs
- WebPartEditorApplyVerb.cs
- MimeParameterWriter.cs
- RoutedEventArgs.cs
- ReflectTypeDescriptionProvider.cs
- Encoder.cs
- PointCollection.cs
- CommunicationObjectFaultedException.cs
- FrameAutomationPeer.cs
- SingleAnimationBase.cs
- GeneralTransform3DGroup.cs
- ProcessProtocolHandler.cs
- DnsPermission.cs
- IsolatedStoragePermission.cs
- RSAPKCS1KeyExchangeFormatter.cs
- InfoCardX509Validator.cs
- MessageEncodingBindingElementImporter.cs
- DrawingState.cs
- TripleDESCryptoServiceProvider.cs
- DebugHandleTracker.cs
- MulticastIPAddressInformationCollection.cs
- CatalogZoneAutoFormat.cs
- DateTimeParse.cs
- ContourSegment.cs
- KeyPullup.cs
- BuildManager.cs
- FaultReasonText.cs
- EraserBehavior.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- SimpleMailWebEventProvider.cs
- TextServicesCompartmentEventSink.cs
- WebPartVerbsEventArgs.cs
- NodeLabelEditEvent.cs
- FormViewDeletedEventArgs.cs
- ListViewDeletedEventArgs.cs
- SymLanguageVendor.cs
- LayoutInformation.cs
- DeploymentSection.cs
- PartitionResolver.cs
- ExtensionWindowResizeGrip.cs
- CrossContextChannel.cs
- DbConnectionOptions.cs
- SizeConverter.cs
- GlobalizationSection.cs
- TemplateBaseAction.cs