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
- WebResourceAttribute.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- ImageDrawing.cs
- TileBrush.cs
- BitmapDownload.cs
- Point3DConverter.cs
- ConstructorNeedsTagAttribute.cs
- NativeWindow.cs
- SqlVisitor.cs
- loginstatus.cs
- AppDomainProtocolHandler.cs
- ProgressBarHighlightConverter.cs
- TimeEnumHelper.cs
- SqlBulkCopy.cs
- GenericTextProperties.cs
- ZipPackagePart.cs
- TransformationRules.cs
- AlphabeticalEnumConverter.cs
- AttributeTable.cs
- XamlTypeMapper.cs
- MailBnfHelper.cs
- XmlReflectionImporter.cs
- JsonCollectionDataContract.cs
- IconEditor.cs
- StyleTypedPropertyAttribute.cs
- EntityDataSourceEntityTypeFilterItem.cs
- NetTcpBindingCollectionElement.cs
- sqlser.cs
- JsonWriter.cs
- CompositionAdorner.cs
- ConsoleCancelEventArgs.cs
- DataGridViewTextBoxCell.cs
- PathStreamGeometryContext.cs
- LocalizableResourceBuilder.cs
- SqlCommandSet.cs
- WindowsSysHeader.cs
- StylusPoint.cs
- SafePointer.cs
- ResourcePart.cs
- ResXBuildProvider.cs
- Converter.cs
- HttpProcessUtility.cs
- InsufficientMemoryException.cs
- ToolBarButtonClickEvent.cs
- DataTemplate.cs
- JsonServiceDocumentSerializer.cs
- SvcMapFile.cs
- CalendarAutoFormatDialog.cs
- TransformCollection.cs
- SiteMapHierarchicalDataSourceView.cs
- Stroke.cs
- TemplateManager.cs
- DataSourceUtil.cs
- QilCloneVisitor.cs
- WhitespaceReader.cs
- PathStreamGeometryContext.cs
- HighContrastHelper.cs
- ArgumentOutOfRangeException.cs
- SynchronizedInputAdaptor.cs
- PropertyGroupDescription.cs
- HexParser.cs
- IpcServerChannel.cs
- HealthMonitoringSection.cs
- metadatamappinghashervisitor.cs
- UpdatePanelTrigger.cs
- AttributeCollection.cs
- ThreadStaticAttribute.cs
- RequestTimeoutManager.cs
- SiteMapPath.cs
- SchemaTableColumn.cs
- KeyEvent.cs
- DataViewListener.cs
- HtmlInputCheckBox.cs
- IndentedWriter.cs
- ZoneLinkButton.cs
- SettingsSavedEventArgs.cs
- UriSectionReader.cs
- ExtensionQuery.cs
- Odbc32.cs
- FromRequest.cs
- PrintDocument.cs
- dtdvalidator.cs
- ObjectListShowCommandsEventArgs.cs
- ClientProxyGenerator.cs
- DirectionalLight.cs
- SafeNativeMethodsCLR.cs
- AnonymousIdentificationModule.cs
- WebPartVerb.cs
- GeneratedCodeAttribute.cs
- TextOutput.cs
- HotSpotCollection.cs
- UnsettableComboBox.cs
- CompositeFontFamily.cs
- PolyLineSegment.cs
- AlphabeticalEnumConverter.cs
- CommaDelimitedStringAttributeCollectionConverter.cs
- HyperlinkAutomationPeer.cs
- HandleCollector.cs
- Permission.cs
- XmlTextWriter.cs