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
- AdPostCacheSubstitution.cs
- DrawingContext.cs
- Keywords.cs
- PrincipalPermission.cs
- X509Utils.cs
- SimpleType.cs
- GeneralTransform3D.cs
- BuildDependencySet.cs
- CheckedListBox.cs
- ClientData.cs
- SectionUpdates.cs
- FormViewDeleteEventArgs.cs
- SizeAnimation.cs
- DependencyPropertyChangedEventArgs.cs
- ellipse.cs
- ExtendedProtectionPolicy.cs
- X509ChainPolicy.cs
- ellipse.cs
- XmlHelper.cs
- XsltQilFactory.cs
- ObjectQuery_EntitySqlExtensions.cs
- NativeMethods.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- ProcessStartInfo.cs
- ResolvedKeyFrameEntry.cs
- KernelTypeValidation.cs
- GenericAuthenticationEventArgs.cs
- MinimizableAttributeTypeConverter.cs
- Operators.cs
- XmlObjectSerializerReadContext.cs
- MenuItemCollection.cs
- Symbol.cs
- ArrangedElement.cs
- Floater.cs
- XMLSyntaxException.cs
- DbDataReader.cs
- LockedHandleGlyph.cs
- SecureEnvironment.cs
- ListBoxItem.cs
- FileDialog_Vista_Interop.cs
- SqlCachedBuffer.cs
- MailAddress.cs
- DelegatingTypeDescriptionProvider.cs
- SqlDataReaderSmi.cs
- XmlNavigatorFilter.cs
- StickyNote.cs
- EffectiveValueEntry.cs
- ObjectDisposedException.cs
- SmtpNegotiateAuthenticationModule.cs
- InvalidProgramException.cs
- CodeIdentifiers.cs
- BindingsCollection.cs
- RemoteWebConfigurationHostStream.cs
- KeyValuePairs.cs
- GroupStyle.cs
- GridPattern.cs
- userdatakeys.cs
- PaintEvent.cs
- PanningMessageFilter.cs
- XXXInfos.cs
- FileFormatException.cs
- AmbientLight.cs
- Control.cs
- Choices.cs
- FormView.cs
- TextSearch.cs
- HostingPreferredMapPath.cs
- PointF.cs
- DefaultSection.cs
- base64Transforms.cs
- SoapHeaders.cs
- RefreshEventArgs.cs
- TrustExchangeException.cs
- ClientTargetSection.cs
- invalidudtexception.cs
- GridViewHeaderRowPresenter.cs
- SelectionPattern.cs
- ShutDownListener.cs
- ProfileGroupSettings.cs
- BrowserCapabilitiesCodeGenerator.cs
- Line.cs
- TrackingParticipant.cs
- QilPatternFactory.cs
- MessagePropertyDescription.cs
- XmlWriterSettings.cs
- UpdateProgress.cs
- Lasso.cs
- PopupControlService.cs
- FrameworkReadOnlyPropertyMetadata.cs
- DebugViewWriter.cs
- ToolStripItemTextRenderEventArgs.cs
- TimeoutValidationAttribute.cs
- SecondaryViewProvider.cs
- BitmapEffectState.cs
- DesignTimeVisibleAttribute.cs
- RuleSetBrowserDialog.cs
- ConfigXmlComment.cs
- grammarelement.cs
- OdbcConnectionFactory.cs
- RetrieveVirtualItemEventArgs.cs