Code:
/ FX-1434 / FX-1434 / 1.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;
///
///
/// Manages the collection of System.Windows.Forms.BindingManagerBase
/// objects for a Win Form.
///
[DefaultEvent("CollectionChanged")]
public class BindingContext : ICollection {
private Hashtable listManagers;
///
///
///
///
/// Gets the total number of System.Windows.Forms.BindingManagerBases
/// objects.
///
///
int ICollection.Count {
get {
ScrubWeakRefs();
return listManagers.Count;
}
}
///
///
///
///
/// Copies the elements of the collection into a specified array, starting
/// at the collection index.
///
///
void ICollection.CopyTo(Array ar, int index)
{
IntSecurity.UnmanagedCode.Demand();
ScrubWeakRefs();
listManagers.CopyTo(ar, index);
}
///
///
///
///
/// Gets an enumerator for the collection.
///
///
IEnumerator IEnumerable.GetEnumerator()
{
IntSecurity.UnmanagedCode.Demand();
ScrubWeakRefs();
return listManagers.GetEnumerator();
}
///
///
///
///
/// Gets a value indicating whether the collection is read-only.
///
///
public bool IsReadOnly {
get {
return false;
}
}
///
///
///
///
/// Gets a value indicating whether the collection is synchronized.
///
///
bool ICollection.IsSynchronized {
get {
// so the user will know that it has to lock this object
return false;
}
}
///
///
///
/// Gets an object to use for synchronization (thread safety).
///
object ICollection.SyncRoot {
get {
return null;
}
}
///
///
/// Initializes a new instance of the System.Windows.Forms.BindingContext class.
///
public BindingContext() {
listManagers = new Hashtable();
}
///
///
///
/// Gets the System.Windows.Forms.BindingManagerBase
/// associated with the specified data source.
///
///
public BindingManagerBase this[object dataSource] {
get {
return this[dataSource, ""];
}
}
///
///
/// Gets the System.Windows.Forms.BindingManagerBase associated with the specified data source and
/// data member.
///
public BindingManagerBase this[object dataSource, string dataMember] {
get {
return EnsureListManager(dataSource, dataMember);
}
}
///
///
/// 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);
}
///
///
///
/// Occurs when the collection has changed.
///
///
[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 {
}
}
///
///
/// 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));
}
///
///
///
/// Clears the collection.
///
///
protected virtual void ClearCore() {
/* !!THIS METHOD IS OBSOLETE AND UNUSED!! */
listManagers.Clear();
}
///
///
/// Gets a value indicating whether the System.Windows.Forms.BindingContext
/// contains the specified
/// data source.
///
public bool Contains(object dataSource) {
return Contains(dataSource, "");
}
///
///
/// Gets a value indicating whether the System.Windows.Forms.BindingContext
/// contains the specified data source and data member.
///
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);
}
///
///
///
///
//
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
- TabControlCancelEvent.cs
- InstanceNotReadyException.cs
- TagPrefixCollection.cs
- CursorConverter.cs
- ForAllOperator.cs
- ExpressionVisitorHelpers.cs
- DataServiceConfiguration.cs
- TemplateKey.cs
- DynamicEntity.cs
- WindowsTokenRoleProvider.cs
- CurrentChangedEventManager.cs
- Registry.cs
- MultiDataTrigger.cs
- CorrelationService.cs
- WriteTimeStream.cs
- WorkflowQueue.cs
- Executor.cs
- EntityChangedParams.cs
- relpropertyhelper.cs
- Validator.cs
- RegexWorker.cs
- Formatter.cs
- ReadWriteControlDesigner.cs
- ManagedWndProcTracker.cs
- TransformProviderWrapper.cs
- ValueTypeFieldReference.cs
- DataListItemEventArgs.cs
- RenderOptions.cs
- SchemaNamespaceManager.cs
- FixedSOMSemanticBox.cs
- ClientTarget.cs
- InplaceBitmapMetadataWriter.cs
- SafeCryptContextHandle.cs
- TextDecorationLocationValidation.cs
- AccessedThroughPropertyAttribute.cs
- ContentPresenter.cs
- ItemDragEvent.cs
- DLinqDataModelProvider.cs
- InvalidChannelBindingException.cs
- TextChangedEventArgs.cs
- Vector3D.cs
- coordinator.cs
- Size.cs
- SkewTransform.cs
- LinqDataSourceDeleteEventArgs.cs
- CurrencyWrapper.cs
- SpeechSynthesizer.cs
- XmlWrappingReader.cs
- WebScriptServiceHostFactory.cs
- CommonXSendMessage.cs
- HostProtectionException.cs
- ConnectionConsumerAttribute.cs
- StructuredType.cs
- UTF32Encoding.cs
- DbCommandTree.cs
- TdsParserStaticMethods.cs
- ProxyWebPartManager.cs
- _UncName.cs
- GridViewHeaderRowPresenter.cs
- FieldNameLookup.cs
- ReadOnlyCollectionBuilder.cs
- hebrewshape.cs
- ServicePointManagerElement.cs
- ManualResetEvent.cs
- BrowserPolicyValidator.cs
- DesignerSerializationOptionsAttribute.cs
- ExceptionValidationRule.cs
- WebPartConnection.cs
- StagingAreaInputItem.cs
- UpdateManifestForBrowserApplication.cs
- TemporaryBitmapFile.cs
- FloatMinMaxAggregationOperator.cs
- RowsCopiedEventArgs.cs
- StreamingContext.cs
- RC2.cs
- HostedElements.cs
- QueryStringParameter.cs
- ViewGenResults.cs
- QilPatternFactory.cs
- ConnectionStringSettingsCollection.cs
- ExeContext.cs
- DispatcherHookEventArgs.cs
- TableCellCollection.cs
- CustomPopupPlacement.cs
- SchemaRegistration.cs
- xml.cs
- TreeViewAutomationPeer.cs
- Stack.cs
- TextRunCache.cs
- KeyValueSerializer.cs
- ValidationPropertyAttribute.cs
- AuditLogLocation.cs
- XPathNodeList.cs
- TemplateBaseAction.cs
- ADRole.cs
- bidPrivateBase.cs
- SByte.cs
- IndexOutOfRangeException.cs
- HwndMouseInputProvider.cs
- ListView.cs