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
- Preprocessor.cs
- WorkflowLayouts.cs
- TypeUnloadedException.cs
- XmlImplementation.cs
- XPathItem.cs
- DataGridDetailsPresenterAutomationPeer.cs
- ToolStripButton.cs
- AlignmentYValidation.cs
- IsolatedStorageFile.cs
- ServiceOperationParameter.cs
- IriParsingElement.cs
- ScriptingRoleServiceSection.cs
- KeyGesture.cs
- TableRow.cs
- LazyTextWriterCreator.cs
- AdjustableArrowCap.cs
- AuthenticationService.cs
- GeneratedView.cs
- SequentialOutput.cs
- GridViewSortEventArgs.cs
- Privilege.cs
- CreateUserWizard.cs
- ToolStripItem.cs
- PixelFormat.cs
- ExecutionEngineException.cs
- Label.cs
- MimePart.cs
- XmlByteStreamReader.cs
- SuppressIldasmAttribute.cs
- NullableDecimalAverageAggregationOperator.cs
- TdsParserSafeHandles.cs
- ChangeConflicts.cs
- DataKeyCollection.cs
- WebReferencesBuildProvider.cs
- IgnoreFlushAndCloseStream.cs
- HttpListenerResponse.cs
- WmiInstallComponent.cs
- InitializationEventAttribute.cs
- ReflectionUtil.cs
- VariableAction.cs
- InputManager.cs
- smtpconnection.cs
- PropertySet.cs
- X509UI.cs
- ModifierKeysValueSerializer.cs
- CornerRadius.cs
- OperationResponse.cs
- XamlDesignerSerializationManager.cs
- SHA384.cs
- InheritedPropertyChangedEventArgs.cs
- LabelLiteral.cs
- ProtocolsConfiguration.cs
- FirstMatchCodeGroup.cs
- SqlInternalConnection.cs
- FixedNode.cs
- RandomNumberGenerator.cs
- SettingsProperty.cs
- DefaultProxySection.cs
- KeyPullup.cs
- ArraySubsetEnumerator.cs
- DateTimePicker.cs
- ResourceDescriptionAttribute.cs
- ActiveXContainer.cs
- _UriTypeConverter.cs
- XslVisitor.cs
- SpellerHighlightLayer.cs
- Convert.cs
- WindowsTab.cs
- BitmapMetadataBlob.cs
- RawKeyboardInputReport.cs
- ExpandButtonVisibilityConverter.cs
- ButtonField.cs
- RowToParametersTransformer.cs
- versioninfo.cs
- Base64Stream.cs
- CheckBoxBaseAdapter.cs
- ScrollProperties.cs
- WebReferencesBuildProvider.cs
- AuthenticationModuleElementCollection.cs
- IChannel.cs
- TextDecorationUnitValidation.cs
- SerTrace.cs
- util.cs
- DataGridHeaderBorder.cs
- _Connection.cs
- PropagatorResult.cs
- ReferencedType.cs
- ValidationResult.cs
- DbConnectionFactory.cs
- CollectionChangedEventManager.cs
- AndCondition.cs
- HttpModuleAction.cs
- Light.cs
- LinkedResourceCollection.cs
- DomainUpDown.cs
- PeerCustomResolverBindingElement.cs
- Soap.cs
- ReferencedAssembly.cs
- CreateBookmarkScope.cs
- ControlCommandSet.cs