Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / ClassHandlersStore.cs / 1305600 / ClassHandlersStore.cs
using System; using System.Diagnostics; using MS.Utility; namespace System.Windows { // Container for the class event handlers // ClassHandlersStore constitues lists of // RoutedEventHandlerInfo keyed on the // RoutedEvent internal class ClassHandlersStore { #region Construction // Constructor for ClassHandlersStore internal ClassHandlersStore(int size) { _eventHandlersList = new ItemStructList(size); } #endregion Construction #region Operations // Adds a routed event handler at the given index of the store // Returns updated set of handlers // NOTE: index must be valid, i.e. not -1 internal RoutedEventHandlerInfoList AddToExistingHandlers( int index, Delegate handler, bool handledEventsToo) { Debug.Assert(index != -1, "There should exist a set of handlers for the given routedEvent"); // Create a new RoutedEventHandler RoutedEventHandlerInfo routedEventHandlerInfo = new RoutedEventHandlerInfo(handler, handledEventsToo); // Check if we need to create a new node in the linked list RoutedEventHandlerInfoList handlers = _eventHandlersList.List[index].Handlers; if (handlers == null || _eventHandlersList.List[index].HasSelfHandlers == false) { // Create a new node in the linked list of class // handlers for this type and routed event. handlers = new RoutedEventHandlerInfoList(); handlers.Handlers = new RoutedEventHandlerInfo[1]; handlers.Handlers[0] = routedEventHandlerInfo; handlers.Next = _eventHandlersList.List[index].Handlers; _eventHandlersList.List[index].Handlers = handlers; _eventHandlersList.List[index].HasSelfHandlers = true; } else { // Add this handler to the existing node in the linked list // of class handlers for this type and routed event. int length = handlers.Handlers.Length; RoutedEventHandlerInfo[] mergedHandlers = new RoutedEventHandlerInfo[length + 1]; Array.Copy(handlers.Handlers, 0, mergedHandlers, 0, length); mergedHandlers[length] = routedEventHandlerInfo; handlers.Handlers = mergedHandlers; } return handlers; } // Returns EventHandlers stored at the given index in the datastructure // NOTE: index must be valid, i.e. not -1 internal RoutedEventHandlerInfoList GetExistingHandlers(int index) { Debug.Assert(index != -1, "There should exist a set of handlers for the given index"); return _eventHandlersList.List[index].Handlers; } // Creates reference to given handlers and RoutedEvent // Returns the index at which the new reference was added // NOTE: There should not exist a set of handlers for the // given routedEvent internal int CreateHandlersLink(RoutedEvent routedEvent, RoutedEventHandlerInfoList handlers) { Debug.Assert(GetHandlersIndex(routedEvent) == -1, "There should not exist a set of handlers for the given routedEvent"); ClassHandlers classHandlers = new ClassHandlers(); classHandlers.RoutedEvent = routedEvent; classHandlers.Handlers = handlers; classHandlers.HasSelfHandlers = false; _eventHandlersList.Add(classHandlers); return _eventHandlersList.Count - 1; } // Update Sub Class Handlers with the given base class listeners // NOTE : Do not wastefully try to update subclass listeners when // base class listeners are null internal void UpdateSubClassHandlers( RoutedEvent routedEvent, RoutedEventHandlerInfoList baseClassListeners) { Debug.Assert(baseClassListeners != null, "Update only when there are base class listeners to be updated"); // Get the handlers index corresponding to the given RoutedEvent int index = GetHandlersIndex(routedEvent); if (index != -1) { bool hasSelfHandlers = _eventHandlersList.List[index].HasSelfHandlers; // Fetch the handlers for your baseType that the current node knows of RoutedEventHandlerInfoList handlers = hasSelfHandlers ? _eventHandlersList.List[index].Handlers.Next : _eventHandlersList.List[index].Handlers; bool needToChange = false; // If the current node has baseType handlers check if the baseClassListeners // provided is for a super type of that baseType. If it is then you will // replace the baseType handlers for the current node with the provided // baseClassListeners. If the given baseClassListeners is for a sub type // of the current nodes's baseType then we do not need to update the current node. // // Example: Consider the following class hierarchy A -> B -> C. // // Now imagine that we register class handlers in the following order. // 1. Register class handler for A. // - A's linked list will be A -> NULL. // - B's linked list will be NULL. // - C's linked list will be NULL. // 2. Register class handler for C. // - A's linked list will be A -> NULL. // - B's linkedList will be NULL. // - C's linked list will be C -> A -> NULL. // 3. Register class handler for B. // - A's linked list will be A -> NULL. // - B's linkedList will be B -> A -> NULL. // - While updating C's linked list we are given B's linked list for the baseClassListers. // Now we want to check if B is a super type of A which is the current baseType that C // knows of. The contains check below determines this. Since it is we now replace C.Next // to be B. Thus we get C -> B -> A -> NULL. // // Now imagine that we register class handlers in the following order. // 1. Register class handler for C. // - A's linked list will be NULL. // - B's linked list will be NULL. // - C's linked list will be C -> NULL. // 2. Register class handler for B. // - A's linked list will be NULL. // - B's linkedList will be B -> NULL. // - While updating C's linked list we are given B's linked list for the baseClassListeners. // Since C does not know of any baseType listeners already it takes the given // baseClassListeners as is. Thus it has C -> B -> NULL // 3. Register class handler for A. // - A's linked list will be A -> NULL. // - B's linkedList will be B -> A -> NULL. // - While updating C's linked list we are given A's linked list for the baseClassListers. // Now we want to check if A is a super type of B which is the current baseType that C // knows of. The contains check below determines this. Since it isn't we do not need to // change the linked list for C. Since B's linked list has already been updated we get // C -> B - > A -> NULL. if (handlers != null) { if (baseClassListeners.Next != null && baseClassListeners.Next.Contains(handlers)) { needToChange = true; } } // If the current node does not have any baseType handlers then if will // simply use the given baseClassListeners. else { needToChange = true; } if (needToChange) { // If current node has self handlers then its next pointer // needs update if not the current node needs update. if (hasSelfHandlers) { _eventHandlersList.List[index].Handlers.Next = baseClassListeners; } else { _eventHandlersList.List[index].Handlers = baseClassListeners; } } } } // Returns EventHandlers Index for the given RoutedEvent internal int GetHandlersIndex(RoutedEvent routedEvent) { // Linear Search for (int i=0; i<_eventHandlersList.Count; i++) { if (_eventHandlersList.List[i].RoutedEvent == routedEvent) { return i; } } return -1; } #endregion Operations #region Data // Stores list of ClassHandlers keyed on RoutedEvent private ItemStructList _eventHandlersList; #endregion Data } // Stores ClassHandlers for the given RoutedEvent internal struct ClassHandlers { #region Operations /// /// Is the given object equals the current /// public override bool Equals(object o) { return Equals((ClassHandlers)o); } ////// Is the given ClassHandlers struct equals the current /// public bool Equals(ClassHandlers classHandlers) { return ( classHandlers.RoutedEvent == this.RoutedEvent && classHandlers.Handlers == this.Handlers); } ////// Serves as a hash function for a particular type, suitable for use in /// hashing algorithms and data structures like a hash table /// public override int GetHashCode() { return base.GetHashCode(); } ////// Equals operator overload /// public static bool operator== (ClassHandlers classHandlers1, ClassHandlers classHandlers2) { return classHandlers1.Equals(classHandlers2); } ////// NotEquals operator overload /// public static bool operator!= (ClassHandlers classHandlers1, ClassHandlers classHandlers2) { return !classHandlers1.Equals(classHandlers2); } #endregion Operations #region Data internal RoutedEvent RoutedEvent; internal RoutedEventHandlerInfoList Handlers; internal bool HasSelfHandlers; #endregion Data } ////// This data-structure represents a linked list of all /// the Class Handlers for a type and its base types. /// internal class RoutedEventHandlerInfoList { internal RoutedEventHandlerInfo[] Handlers; internal RoutedEventHandlerInfoList Next; internal bool Contains(RoutedEventHandlerInfoList handlers) { RoutedEventHandlerInfoList tempHandlers = this; while (tempHandlers != null) { if (tempHandlers == handlers) { return true; } tempHandlers = tempHandlers.Next; } return false; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- GridViewItemAutomationPeer.cs
- SqlParameterCollection.cs
- EntitySqlQueryCacheKey.cs
- DoubleAnimationUsingKeyFrames.cs
- ObjectDataSource.cs
- XmlIlVisitor.cs
- XmlSchemaAny.cs
- FrugalList.cs
- BasicKeyConstraint.cs
- StickyNoteAnnotations.cs
- ListViewInsertEventArgs.cs
- CredentialCache.cs
- ListCollectionView.cs
- ProtocolElementCollection.cs
- TableCellAutomationPeer.cs
- ConnectionPointGlyph.cs
- DetailsViewDeleteEventArgs.cs
- ResourceAssociationTypeEnd.cs
- RegistryConfigurationProvider.cs
- FolderBrowserDialog.cs
- KnownBoxes.cs
- PrintDocument.cs
- GridViewUpdateEventArgs.cs
- AnnotationComponentManager.cs
- SqlDataSourceEnumerator.cs
- TargetInvocationException.cs
- XsltLoader.cs
- CodeExpressionCollection.cs
- PhysicalAddress.cs
- xmlfixedPageInfo.cs
- ScrollBarAutomationPeer.cs
- TableAdapterManagerMethodGenerator.cs
- FixedLineResult.cs
- WebScriptMetadataMessageEncoderFactory.cs
- PageContentCollection.cs
- EmptyReadOnlyDictionaryInternal.cs
- InvalidEnumArgumentException.cs
- CommandBindingCollection.cs
- Version.cs
- CategoriesDocumentFormatter.cs
- webeventbuffer.cs
- FrugalList.cs
- AnimatedTypeHelpers.cs
- XmlSchemaAttributeGroupRef.cs
- ListBox.cs
- Camera.cs
- XmlDocumentFragment.cs
- DBCommand.cs
- ComplusTypeValidator.cs
- ParseNumbers.cs
- XmlObjectSerializerWriteContextComplex.cs
- PropertyValueChangedEvent.cs
- NegatedCellConstant.cs
- ObjectStorage.cs
- SchemaTypeEmitter.cs
- GenerateTemporaryAssemblyTask.cs
- XmlSchemaException.cs
- MulticastOption.cs
- DefaultPrintController.cs
- ManifestResourceInfo.cs
- WebPartConnectionsDisconnectVerb.cs
- MenuItemStyleCollectionEditor.cs
- PixelFormatConverter.cs
- cookiecollection.cs
- Rect3D.cs
- Fault.cs
- KerberosSecurityTokenProvider.cs
- TextChangedEventArgs.cs
- ObjectReaderCompiler.cs
- ProxyWebPart.cs
- x509store.cs
- SingleObjectCollection.cs
- BatchWriter.cs
- XmlUTF8TextReader.cs
- DataGridState.cs
- MD5CryptoServiceProvider.cs
- TransactionManager.cs
- OpenCollectionAsyncResult.cs
- SecurityDocument.cs
- UniqueConstraint.cs
- TypedTableBaseExtensions.cs
- X509Certificate2Collection.cs
- ClaimSet.cs
- Cursors.cs
- CallSiteOps.cs
- RenderCapability.cs
- TextEffectCollection.cs
- SqlBuilder.cs
- GenericRootAutomationPeer.cs
- StatusStrip.cs
- StandardToolWindows.cs
- ConfigurationStrings.cs
- DataGridTable.cs
- TitleStyle.cs
- FilteredXmlReader.cs
- InvokeMethodActivityDesigner.cs
- PhysicalAddress.cs
- DataRecordInfo.cs
- StringUtil.cs
- UIElementParaClient.cs