Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / System / Windows / ClassHandlersStore.cs / 1 / 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. 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
- DesignerObject.cs
- ServiceObjectContainer.cs
- DataControlButton.cs
- StyleXamlParser.cs
- LocatorGroup.cs
- XmlSchemaAttributeGroupRef.cs
- Stack.cs
- SpellerInterop.cs
- Substitution.cs
- TextRangeAdaptor.cs
- ConfigurationStrings.cs
- IconEditor.cs
- XmlSchemaComplexContentExtension.cs
- AssemblyHash.cs
- AuthenticationModuleElementCollection.cs
- EntityDataSourceValidationException.cs
- BaseValidator.cs
- __Filters.cs
- ControlValuePropertyAttribute.cs
- XmlDataSourceView.cs
- CompositeKey.cs
- XPathSelectionIterator.cs
- StagingAreaInputItem.cs
- SoapReflectionImporter.cs
- DesignTimeHTMLTextWriter.cs
- AstNode.cs
- Pens.cs
- PaginationProgressEventArgs.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- ConfigurationSectionGroupCollection.cs
- BooleanAnimationBase.cs
- ViewManager.cs
- DoWorkEventArgs.cs
- EntityAdapter.cs
- XmlElementCollection.cs
- EventHandlingScope.cs
- ScrollChrome.cs
- HotSpotCollection.cs
- DriveInfo.cs
- WorkflowElementDialog.cs
- ZipIOCentralDirectoryBlock.cs
- DispatcherSynchronizationContext.cs
- ArrayList.cs
- RenderCapability.cs
- SafeSecurityHandles.cs
- SizeAnimationUsingKeyFrames.cs
- ResourceManager.cs
- ReferencedAssemblyResolver.cs
- PersonalizationState.cs
- HttpResponse.cs
- Padding.cs
- BuildProvider.cs
- Visual3DCollection.cs
- LiteralControl.cs
- SecurityDescriptor.cs
- XmlSchemaAny.cs
- EmptyEnumerator.cs
- QueryTask.cs
- SqlConnectionPoolProviderInfo.cs
- LocalizationComments.cs
- SendActivityEventArgs.cs
- CommonObjectSecurity.cs
- WebPartUserCapability.cs
- RemotingAttributes.cs
- PermissionAttributes.cs
- SetUserPreferenceRequest.cs
- CodeGenerator.cs
- AtomServiceDocumentSerializer.cs
- RecognizedPhrase.cs
- TranslateTransform.cs
- Selection.cs
- SmtpReplyReader.cs
- UriTemplateMatchException.cs
- PrimitiveCodeDomSerializer.cs
- Ray3DHitTestResult.cs
- XPathNavigatorKeyComparer.cs
- CorrelationService.cs
- PropertyEntry.cs
- Transform.cs
- HtmlElementCollection.cs
- UrlPath.cs
- InputDevice.cs
- Selection.cs
- TargetInvocationException.cs
- TimelineGroup.cs
- PeerCredential.cs
- CursorConverter.cs
- SqlDataSourceQueryEditorForm.cs
- CssClassPropertyAttribute.cs
- CollectionView.cs
- WebPartUserCapability.cs
- SafeCancelMibChangeNotify.cs
- ServiceOperationParameter.cs
- ServicesUtilities.cs
- OutOfProcStateClientManager.cs
- ValidatingCollection.cs
- CalendarData.cs
- DetailsViewRow.cs
- RenderData.cs
- GregorianCalendar.cs