Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / BindingContext.cs / 1 / BindingContext.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System; using Microsoft.Win32; using System.ComponentModel; using System.Collections; using System.Globalization; using System.Diagnostics.CodeAnalysis; ////// /// [DefaultEvent("CollectionChanged")] public class BindingContext : ICollection { private Hashtable listManagers; ///Manages the collection of System.Windows.Forms.BindingManagerBase /// objects for a Win Form. ////// /// /// int ICollection.Count { get { ScrubWeakRefs(); return listManagers.Count; } } ////// Gets the total number of System.Windows.Forms.BindingManagerBases /// objects. /// ////// /// /// void ICollection.CopyTo(Array ar, int index) { IntSecurity.UnmanagedCode.Demand(); ScrubWeakRefs(); listManagers.CopyTo(ar, index); } ////// Copies the elements of the collection into a specified array, starting /// at the collection index. /// ////// /// /// IEnumerator IEnumerable.GetEnumerator() { IntSecurity.UnmanagedCode.Demand(); ScrubWeakRefs(); return listManagers.GetEnumerator(); } ////// Gets an enumerator for the collection. /// ////// /// /// public bool IsReadOnly { get { return false; } } ////// Gets a value indicating whether the collection is read-only. /// ////// /// /// bool ICollection.IsSynchronized { get { // so the user will know that it has to lock this object return false; } } ////// Gets a value indicating whether the collection is synchronized. /// ////// /// /// object ICollection.SyncRoot { get { return null; } } ///Gets an object to use for synchronization (thread safety). ////// /// public BindingContext() { listManagers = new Hashtable(); } ///Initializes a new instance of the System.Windows.Forms.BindingContext class. ////// /// public BindingManagerBase this[object dataSource] { get { return this[dataSource, ""]; } } ////// Gets the System.Windows.Forms.BindingManagerBase /// associated with the specified data source. /// ////// /// public BindingManagerBase this[object dataSource, string dataMember] { get { return EnsureListManager(dataSource, dataMember); } } ///Gets the System.Windows.Forms.BindingManagerBase associated with the specified data source and /// data member. ////// /// Adds the listManager to the collection. An ArgumentNullException is thrown if this listManager /// is null. An exception is thrown if a listManager to the same target and Property as an existing listManager or /// if the listManager's column isn't a valid column given this DataSource.Table's schema. /// Fires the CollectionChangedEvent. /// internal protected void Add(object dataSource, BindingManagerBase listManager) { /* !!THIS METHOD IS OBSOLETE AND UNUSED!! */ AddCore(dataSource, listManager); OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Add, dataSource)); } ////// /// protected virtual void AddCore(object dataSource, BindingManagerBase listManager) { /* !!THIS METHOD IS OBSOLETE AND UNUSED!! */ if (dataSource == null) throw new ArgumentNullException("dataSource"); if (listManager == null) throw new ArgumentNullException("listManager"); // listManagers[dataSource] = listManager; listManagers[GetKey(dataSource, "")] = new WeakReference(listManager, false); } ////// /// [SRDescription(SR.collectionChangedEventDescr), EditorBrowsable(EditorBrowsableState.Never), Browsable(false)] public event CollectionChangeEventHandler CollectionChanged { /* !!THIS EVENT IS OBSOLETE AND UNUSED!! */ [SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters")] add { throw new NotImplementedException(); } [SuppressMessage("Microsoft.Performance", "CA1801:AvoidUnusedParameters")] remove { } } ////// Occurs when the collection has changed. /// ////// /// Clears the collection of any bindings. /// Fires the CollectionChangedEvent. /// internal protected void Clear() { /* !!THIS METHOD IS OBSOLETE AND UNUSED!! */ ClearCore(); OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, null)); } ////// /// protected virtual void ClearCore() { /* !!THIS METHOD IS OBSOLETE AND UNUSED!! */ listManagers.Clear(); } ////// Clears the collection. /// ////// /// public bool Contains(object dataSource) { return Contains(dataSource, ""); } ///Gets a value indicating whether the System.Windows.Forms.BindingContext /// contains the specified /// data source. ////// /// public bool Contains(object dataSource, string dataMember) { return listManagers.ContainsKey(GetKey(dataSource, dataMember)); } internal HashKey GetKey(object dataSource, string dataMember) { return new HashKey(dataSource, dataMember); } ///Gets a value indicating whether the System.Windows.Forms.BindingContext /// contains the specified data source and data member. ////// /// /// // internal class HashKey { WeakReference wRef; int dataSourceHashCode; string dataMember; internal HashKey(object dataSource, string dataMember) { if (dataSource == null) throw new ArgumentNullException("dataSource"); if (dataMember == null) dataMember = ""; // The dataMember should be case insensitive. // so convert the dataMember to lower case // this.wRef = new WeakReference(dataSource, false); this.dataSourceHashCode = dataSource.GetHashCode(); this.dataMember = dataMember.ToLower(CultureInfo.InvariantCulture); } ////// /// /// public override int GetHashCode() { return dataSourceHashCode * dataMember.GetHashCode(); } ////// /// /// public override bool Equals(object target) { if (target is HashKey) { HashKey keyTarget = (HashKey)target; return wRef.Target == keyTarget.wRef.Target && dataMember == keyTarget.dataMember; } return false; } } ////// /// /// This method is called whenever the collection changes. Overriders /// of this method should call the base implementation of this method. /// NOTE: This shipped in Everett, so we need to keep it, but we don't do /// anything here. /// protected virtual void OnCollectionChanged(CollectionChangeEventArgs ccevent) { } ////// /// Removes the given listManager from the collection. /// An ArgumentNullException is thrown if this listManager is null. An ArgumentException is thrown /// if this listManager doesn't belong to this collection. /// The CollectionChanged event is fired if it succeeds. /// internal protected void Remove(object dataSource) { /* !!THIS METHOD IS OBSOLETE AND UNUSED!! */ RemoveCore(dataSource); OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Remove, dataSource)); } ////// /// /// protected virtual void RemoveCore(object dataSource) { /* !!THIS METHOD IS OBSOLETE AND UNUSED!! */ listManagers.Remove(GetKey(dataSource, "")); } ////// /// Create a suitable binding manager for the specified dataSource/dataMember combination. /// - If one has already been created and cached by this BindingContext, return that instead. /// - If the data source is an ICurrencyManagerProvider, just delegate to the data source. /// internal BindingManagerBase EnsureListManager(object dataSource, string dataMember) { BindingManagerBase bindingManagerBase = null; if (dataMember == null) dataMember = ""; // Check whether data source wants to provide its own binding managers // (but fall through to old logic if it fails to provide us with one) // if (dataSource is ICurrencyManagerProvider) { bindingManagerBase = (dataSource as ICurrencyManagerProvider).GetRelatedCurrencyManager(dataMember); if (bindingManagerBase != null) { return bindingManagerBase; } } // Check for previously created binding manager // HashKey key = GetKey(dataSource, dataMember); WeakReference wRef; wRef = listManagers[key] as WeakReference; if (wRef != null) bindingManagerBase = (BindingManagerBase) wRef.Target; if (bindingManagerBase != null) { return bindingManagerBase; } if (dataMember.Length == 0) { // No data member specified, so create binding manager directly on the data source // if (dataSource is IList || dataSource is IListSource) { // IListSource so we can bind the dataGrid to a table and a dataSet bindingManagerBase = new CurrencyManager(dataSource); } else { // Otherwise assume simple property binding bindingManagerBase = new PropertyManager(dataSource); } } else { // Data member specified, so get data source's binding manager, and hook a 'related' binding manager to it // int lastDot = dataMember.LastIndexOf("."); string dataPath = (lastDot == -1) ? "" : dataMember.Substring(0, lastDot); string dataField = dataMember.Substring(lastDot + 1); BindingManagerBase formerManager = EnsureListManager(dataSource, dataPath); PropertyDescriptor prop = formerManager.GetItemProperties().Find(dataField, true); if (prop == null) throw new ArgumentException(SR.GetString(SR.RelatedListManagerChild, dataField)); if (typeof(IList).IsAssignableFrom(prop.PropertyType)) bindingManagerBase = new RelatedCurrencyManager(formerManager, dataField); else bindingManagerBase = new RelatedPropertyManager(formerManager, dataField); } // if wRef == null, then it is the first time we want this bindingManagerBase: so add it // if wRef != null, then the bindingManagerBase was GC'ed at some point: keep the old wRef and change its target if (wRef == null) listManagers.Add(key, new WeakReference(bindingManagerBase, false)); else wRef.Target = bindingManagerBase; // Return the final binding manager return bindingManagerBase; } // may throw private static void CheckPropertyBindingCycles(BindingContext newBindingContext, Binding propBinding) { if (newBindingContext == null || propBinding == null) return; if (newBindingContext.Contains(propBinding.BindableComponent, "")) { // this way we do not add a bindingManagerBase to the // bindingContext if there isn't one already BindingManagerBase bindingManagerBase = newBindingContext.EnsureListManager(propBinding.BindableComponent, ""); for (int i = 0; i < bindingManagerBase.Bindings.Count; i++) { Binding binding = bindingManagerBase.Bindings[i]; if (binding.DataSource == propBinding.BindableComponent) { if (propBinding.BindToObject.BindingMemberInfo.BindingMember.Equals(binding.PropertyName)) throw new ArgumentException(SR.GetString(SR.DataBindingCycle, binding.PropertyName), "propBinding"); } else if (propBinding.BindToObject.BindingManagerBase is PropertyManager) CheckPropertyBindingCycles(newBindingContext, binding); } } } private void ScrubWeakRefs() { object[] list = new object[listManagers.Count]; listManagers.CopyTo(list, 0); for (int i = 0; i < list.Length; i++) { DictionaryEntry entry = (DictionaryEntry) list[i]; WeakReference wRef = (WeakReference) entry.Value; if (wRef.Target == null) { listManagers.Remove(entry.Key); } } } ////// /// Associates a Binding with a different BindingContext. Intended for use by components that support /// IBindableComponent, to update their Bindings when the value of IBindableComponent.BindingContext /// is changed. /// public static void UpdateBinding(BindingContext newBindingContext, Binding binding) { BindingManagerBase oldManager = binding.BindingManagerBase; if (oldManager != null) { oldManager.Bindings.Remove(binding); } if (newBindingContext != null) { // we need to first check for cycles before adding this binding to the collection // of bindings. if (binding.BindToObject.BindingManagerBase is PropertyManager) CheckPropertyBindingCycles(newBindingContext, binding); BindToObject bindTo = binding.BindToObject; BindingManagerBase newManager = newBindingContext.EnsureListManager(bindTo.DataSource, bindTo.BindingMemberInfo.BindingPath); newManager.Bindings.Add(binding); } } } } // 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
- Overlapped.cs
- StorageSetMapping.cs
- Utilities.cs
- IndexExpression.cs
- entityreference_tresulttype.cs
- MarshalByValueComponent.cs
- KeyInterop.cs
- ApplicationDirectoryMembershipCondition.cs
- WebPartManagerInternals.cs
- CodeSubDirectoriesCollection.cs
- ObsoleteAttribute.cs
- DomainConstraint.cs
- CompiledIdentityConstraint.cs
- MouseGestureValueSerializer.cs
- DateBoldEvent.cs
- ObjectPropertyMapping.cs
- MappingModelBuildProvider.cs
- FixedSOMFixedBlock.cs
- OperationCanceledException.cs
- ObjectAssociationEndMapping.cs
- DesignTimeTemplateParser.cs
- ServerIdentity.cs
- ValidationHelper.cs
- TrackingMemoryStream.cs
- KnownTypesHelper.cs
- returneventsaver.cs
- LinkedResourceCollection.cs
- Throw.cs
- ProxyGenerationError.cs
- EncoderFallback.cs
- ProgressChangedEventArgs.cs
- Serializer.cs
- ComplexType.cs
- counter.cs
- XmlHierarchicalDataSourceView.cs
- Comparer.cs
- StringAnimationUsingKeyFrames.cs
- MgmtResManager.cs
- IODescriptionAttribute.cs
- FontInfo.cs
- AssemblyBuilderData.cs
- TypeBrowser.xaml.cs
- ErrorInfoXmlDocument.cs
- SqlReorderer.cs
- DefaultClaimSet.cs
- _NegoStream.cs
- BitArray.cs
- TextComposition.cs
- Command.cs
- TextEndOfLine.cs
- WrapperEqualityComparer.cs
- ParserContext.cs
- ConfigurationSchemaErrors.cs
- TransformerInfo.cs
- Pair.cs
- WindowShowOrOpenTracker.cs
- CodeCommentStatementCollection.cs
- TemplateField.cs
- RootBuilder.cs
- ClientSettingsStore.cs
- MailHeaderInfo.cs
- XmlSchemaValidationException.cs
- FixedTextContainer.cs
- Metadata.cs
- ProvidersHelper.cs
- SRef.cs
- WebPartEditorCancelVerb.cs
- XmlSchemaGroup.cs
- DesignOnlyAttribute.cs
- Button.cs
- WebBrowserUriTypeConverter.cs
- ProgressBarHighlightConverter.cs
- OdbcEnvironmentHandle.cs
- WinCategoryAttribute.cs
- ISCIIEncoding.cs
- RegexParser.cs
- MatrixUtil.cs
- CustomAttributeFormatException.cs
- EmptyStringExpandableObjectConverter.cs
- PropagatorResult.cs
- documentation.cs
- LabelEditEvent.cs
- RangeValuePattern.cs
- ToolboxService.cs
- XamlVector3DCollectionSerializer.cs
- StickyNoteAnnotations.cs
- ObjectDataSource.cs
- MetaTableHelper.cs
- OleServicesContext.cs
- TemplatedWizardStep.cs
- WindowsFormsHostAutomationPeer.cs
- SkinBuilder.cs
- WebPartConnectionsCloseVerb.cs
- RawStylusInputCustomData.cs
- CatalogZone.cs
- PageOutputQuality.cs
- UriParserTemplates.cs
- TextSegment.cs
- InputElement.cs
- XPathArrayIterator.cs