//Lazy<IValueConverter> _defaultConverter; //public virtual Lazy<IValueConverter> DefaultConverter //{ // get // { // if(_defaultConverter == null) // { // return new Lazy<IValueConverter>(() => new PropValueConverter()); // } // return _defaultConverter; // } // set // { // _defaultConverter = value; // } //} //Func<BindingTarget, MyBindingInfo, Type, string, object> _defConvParamBuilder; //public virtual Func<BindingTarget, MyBindingInfo, Type, string, object> DefaultConverterParameterBuilder //{ // get // { // if (_defConvParamBuilder == null) // { // return OurDefaultConverterParameterBuilder; // } // return _defConvParamBuilder; // } // set // { // _defConvParamBuilder = value; // } //} #endregion #region Constructor internal LocalBinder(PSAccessServiceInterface propStoreAccessService, LocalBindingInfo bindingInfo, IReceivePropStoreNodeUpdates storeNodeUpdateReceiver) { _propStoreAccessService_wr = new WeakReference <PSAccessServiceInterface>(propStoreAccessService); _bindingInfo = bindingInfo; _storeNodeUpdateReceiver = storeNodeUpdateReceiver; _bindingTarget = new SimpleExKey(); // Get the PropStore Node for the IPropBag object hosting the property that is the target of the binding. // TODO: Instead of doing this now, create a property that allows us to access upon first access. _ourNode = GetPropBagNode(propStoreAccessService); _targetObject = null; _propertyName = null; _targetHasStore = PropStorageStrategyEnum.Virtual; _pathElements = GetPathElements(_bindingInfo, out _isPathAbsolute, out _firstNamedStepIndex); if (_isPathAbsolute) { _rootListener = CreateAndListen(_ourNode, "root", SourceKindEnum.AbsRoot); } else { _rootListener = null; } _pathListeners = new OSCollection <T>(); _isComplete = StartBinding(_targetObject, _pathElements, _pathListeners, _isPathAbsolute); }
// TODO: Consider moving these methods to the OSCollection<T> class. private bool AddOrUpdateListener(IPropBag propBag, ExKeyT compKey, string pathComp, SourceKindEnum sourceKind, OSCollection <T> pathListeners, int nPtr) { bool result; if (pathListeners.Count > nPtr) { ObservableSource <T> listener = pathListeners[nPtr]; if (compKey != listener.CompKey || sourceKind != listener.SourceKind) { listener.Dispose(); ObservableSource <T> newListener = CreateAndListen(propBag, compKey, pathComp, sourceKind); pathListeners[nPtr] = newListener; result = true; } else { result = false; } } else { ObservableSource <T> newListener = CreateAndListen(propBag, compKey, pathComp, sourceKind); pathListeners.Add(newListener); result = true; } return(result); }
// Note since the Target and Method are not set, the default IEquatable implementation does not produce // accurate results. // DRM: Acutally the IEquatable implementation should be ok -- but need to create unit test to be sure. // TODO: Create unit test to verify that the IEquatable implementation for SubscriptionKeyForBinding produces accurate result. // Creates a new Binding Request. protected SubscriptionKeyGen( ExKeyT ownerPropId, Type propertyType, LocalBindingInfo bindingInfo, SubscriptionKind kind, SubscriptionPriorityGroup subscriptionPriorityGroup, Func <ISubscriptionKeyGen, PSAccessServiceInterface, ISubscription> bindingFactory) { OwnerPropId = ownerPropId; // The binding is created on the target, we will go find the source of the events to listen. PropertyType = PropertyType; SubscriptionKind = kind; SubscriptionPriorityGroup = subscriptionPriorityGroup; //SubscriptionTargetKind = SubscriptionTargetKind.GlobalPropId; //GenDoWhenChanged = null; //Action = null; Target_Wrk = WeakRefKey.Empty; Method = null; SubscriptionFactory = null; BindingFactory = bindingFactory; HasBeenUsed = false; // Properties unique to Binding Subscriptions BindingInfo = bindingInfo; }
// Target and Method. Also used for TypeDelegate and TypedAction. public SubscriptionKeyGen(ExKeyT sourcePropId, Type propertyType, object target, MethodInfo method, SubscriptionKind kind, SubscriptionPriorityGroup subscriptionPriorityGroup, bool keepRef, Func <ISubscriptionKeyGen, IProvideHandlerDispatchDelegateCaches, ISubscription> subscriptionFactory) { OwnerPropId = sourcePropId; PropertyType = propertyType; SubscriptionKind = kind; SubscriptionPriorityGroup = subscriptionPriorityGroup; //SubscriptionTargetKind = GetKindOfTarget(target, keepRef); //GenDoWhenChanged = null; //Action = null; if (target == null) { throw new ArgumentNullException(nameof(target)); } Target_Wrk = new WeakRefKey(target); Method = method ?? throw new ArgumentNullException(nameof(method)); SubscriptionFactory = subscriptionFactory ?? CreateSubscriptionGen; BindingFactory = null; HasBeenUsed = false; }
public IEnumerable <ISubscription> TryGetBindings(ExKeyT exKey) { lock (_sync) { IEnumerable <ISubscription> result = _bindings.Where((x => x.OwnerPropId == exKey)); return(result); } }
public bool TryGetPropNode(ExKeyT compKey, out PropNode propNode) { bool result; lock (_sync) { result = _children.TryGetValue(compKey, out propNode); } return(result); }
public ParentNCSubscriptionRequest(ExKeyT sourcePropId, EventHandler <PSNodeParentChangedEventArgs> handler) { OwnerPropId = sourcePropId; object target = handler.Target ?? throw new ArgumentNullException(nameof(handler.Target)); Target_Wrk = new WeakRefKey(target); Method = handler.Method ?? throw new ArgumentNullException(nameof(handler.Method)); SubscriptionFactory = CreateSubscriptionGen; HasBeenUsed = false; }
public ObservableSource(IPropBag propBag, ExKeyT compKey, string pathElement, string binderName) { CompKey = compKey; PathElement = pathElement; BinderName = binderName; SourceKind = SourceKindEnum.TerminalNode; IDisposable disable = propBag.SubscribeToPropChanged <T>(PropertyChangedWithTVals_Handler, pathElement); PropChangedTypedUnsubscriber = disable ?? throw new InvalidOperationException($"Could not subscribe to EventHandler<PcTypedEventArgs<{typeof(T)}>> PropertyChangedWithTVals for {PathElement}."); }
public ObservableSource(IPropBag propBag, ExKeyT compKey, string pathElement, SourceKindEnum sourceKind, string binderName) { CompKey = compKey; PathElement = pathElement; BinderName = binderName; SourceKind = sourceKind; IDisposable disable = propBag.SubscribeToPropChanged(PropertyChangedWithGenVals_Handler, PathElement, typeof(T)); PropChangeGenUnsubscriber = disable ?? throw new InvalidOperationException($"Could not subscribe to EventHandler<PcGenEventArgs> PropertyChangedWithGenVals for {PathElement}."); }
//public EventHandler<PcTypedEventArgs<T>> TypedHandler { get; private set; } //public Action<T, T> TypedDoWhenChanged { get; private set; } #endregion #region Constructors // Typed Handler -- PCTypeEventArgs<T> public SubscriptionKey ( ExKeyT exKey, EventHandler <PcTypedEventArgs <T> > handler, SubscriptionPriorityGroup subscriptionPriorityGroup, bool keepRef ) : base(exKey, typeof(T), target: handler.Target, method: handler.Method, kind: SubscriptionKind.TypedHandler, subscriptionPriorityGroup: subscriptionPriorityGroup, keepRef: keepRef, subscriptionFactory: CreateSubscriptionGen) { //TypedHandler = handler; PropertyType = typeof(T); }
public SubscriptionKey ( ExKeyT exKey, object target, MethodInfo methodInfo, SubscriptionPriorityGroup priorityGroup, bool keepRef ) : base(exKey, typeof(T), target: target, method: methodInfo, kind: SubscriptionKind.TypedHandler, subscriptionPriorityGroup: priorityGroup, keepRef: keepRef, subscriptionFactory: CreateSubscriptionGen) { //TypedHandler = null; PropertyType = typeof(T); }
public PropItemFixedPropertyDescriptor ( PropertyDescriptorValues <T> tdConfig, PSFastAccessServiceInterface psFastAccessService, PropModelType propModel, PropIdType propId ) : base(tdConfig.Name, tdConfig.Attributes) { _tdConfig = tdConfig; _psFastAccessService = psFastAccessService; _propItemSetKey = new PropItemSetKeyType(propModel); PropId = propId; _compKey = new SimpleExKey(10, propId); }
public BindingSubscriptionKey ( ExKeyT ownerPropId, LocalBindingInfo bindingInfo ) : base ( ownerPropId, typeof(T), bindingInfo, SubscriptionKind.LocalBinding, SubscriptionPriorityGroup.First, CreateBindingGen ) { }
public object GetValueFast(ExKeyT compKey, PropItemSetKeyType propItemSetKey) { if (!TryGetSharedPropCollection(propItemSetKey, out PropNodelCollectionSharedInterface sharedPropCollection)) { throw new InvalidOperationException($"Could not retrieve the SharedPropCollection for {propItemSetKey.FullClassName} ."); } if (!sharedPropCollection.TryGetPropNode(compKey, out PropNode propNode)) { throw new KeyNotFoundException($"The {sharedPropCollection} could not retrieve a PropNode for {compKey}."); } object result = propNode.PropData_Internal.TypedProp.TypedValueAsObject; return(result); }
private ObservableSource <T> CreateAndListen(IPropBag propBag, ExKeyT compKey, string pathComp, SourceKindEnum sourceKind) { ObservableSource <T> result; if (sourceKind == SourceKindEnum.Down) { result = new ObservableSource <T>((IPropBag)propBag, compKey, pathComp, sourceKind, BINDER_NAME); result.PropertyChangedWithVals += PropertyChangedWithVals_Handler; } else if (sourceKind == SourceKindEnum.TerminalNode) { result = new ObservableSource <T>((IPropBag)propBag, compKey, pathComp, BINDER_NAME); result.PropertyChangedWithTVals += PropertyChangedWithTVals_Handler; } else { throw new InvalidOperationException($"CreateAndListen when supplied a propBag can only process nodes of source kind = {nameof(SourceKindEnum.Down)} and {nameof(SourceKindEnum.TerminalNode)}."); } return(result); }
//Lazy<IValueConverter> _defaultConverter; //public virtual Lazy<IValueConverter> DefaultConverter //{ // get // { // if(_defaultConverter == null) // { // return new Lazy<IValueConverter>(() => new PropValueConverter()); // } // return _defaultConverter; // } // set // { // _defaultConverter = value; // } //} //Func<BindingTarget, MyBindingInfo, Type, string, object> _defConvParamBuilder; //public virtual Func<BindingTarget, MyBindingInfo, Type, string, object> DefaultConverterParameterBuilder //{ // get // { // if (_defConvParamBuilder == null) // { // return OurDefaultConverterParameterBuilder; // } // return _defConvParamBuilder; // } // set // { // _defConvParamBuilder = value; // } //} #endregion #region Constructor public LocalBinder(PSAccessServiceInterface propStoreAccessService, ExKeyT bindingTarget, LocalBindingInfo bindingInfo) { _bindingTarget = bindingTarget; _bindingInfo = bindingInfo; // Get the PropStore Node for the IPropBag object hosting the property that is the target of the binding. BagNode ourNode = GetPropBagNode(propStoreAccessService); // Get a weak reference to the PropBag hosting the target property. _targetObject = ourNode.PropBagProxy; // Get the name of the target property from the PropId given to us. if (_targetObject.TryGetTarget(out IPropBag propBag)) { PropIdType propId = _bindingTarget.Level2Key; _propertyName = GetPropertyName(propStoreAccessService, propBag, propId, out PropStorageStrategyEnum storageStrategy); if (storageStrategy == PropStorageStrategyEnum.External) { throw new InvalidOperationException($"{storageStrategy} is not a supported Prop Storage Strategy when used as a target of a local binding."); } // We will update the target property depending on how that PropItem stores its value. _targetStorageStrategy = storageStrategy; // Create a instance of our nested, internal class that reponds to Updates to the property store Nodes. IReceivePropStoreNodeUpdates_PropNode <T> propStoreNodeUpdateReceiver = new PropStoreNodeUpdateReceiver(this); // Create a new watcher, the bindingInfo specifies the PropItem for which to listen to changes, // the propStoreNodeUpdateReceiver will be notfied when changes occur. _localWatcher = new LocalWatcher <T>(propStoreAccessService, bindingInfo, propStoreNodeUpdateReceiver); } else { // TODO: consider creating a TryCreateLocalBinding to avoid this situation. System.Diagnostics.Debug.WriteLine("The target was found to have been Garbage Collected when creating a Local Binding."); } }
// Changing PropertyChangingEventHandler public SubscriptionKeyGen(ExKeyT sourcePropId, PropertyChangingEventHandler changingDelegate, SubscriptionPriorityGroup subscriptionPriorityGroup, bool keepRef) { OwnerPropId = sourcePropId; PropertyType = null; SubscriptionKind = SubscriptionKind.ChangingHandler; SubscriptionPriorityGroup = subscriptionPriorityGroup; //SubscriptionTargetKind = GetKindOfTarget(standardDelegate.Target, keepRef); //GenDoWhenChanged = null; //Action = null; object target = changingDelegate.Target ?? throw new ArgumentNullException(nameof(changingDelegate.Target)); Target_Wrk = new WeakRefKey(target); Method = changingDelegate.Method ?? throw new ArgumentNullException(nameof(changingDelegate.Method)); SubscriptionFactory = CreateSubscriptionGen; BindingFactory = null; HasBeenUsed = false; }
public bool SetValueFast(ExKeyT compKey, PropItemSetKeyType propItemSetKey, object value) { if (!TryGetSharedPropCollection(propItemSetKey, out PropNodelCollectionSharedInterface sharedPropCollection)) { throw new InvalidOperationException($"Could not retrieve the SharedPropCollection for {propItemSetKey.FullClassName} ."); } if (!sharedPropCollection.TryGetPropNode(compKey, out PropNode propNode)) { throw new KeyNotFoundException($"The {sharedPropCollection} could not retrieve a PropNode for {compKey}."); } if (!propNode.Parent.TryGetPropBag(out IPropBag propBag)) { // The target has been garbage collected. return(false); } bool result = SetPropValue(propBag, propNode, compKey.Level2Key, value); return(result); }
public ObservableSource(INotifyParentNodeChanged notifyParentChangedSource, ExKeyT compKey, string pathElement, SourceKindEnum sourceKind, string binderName) { CompKey = compKey; PathElement = pathElement; BinderName = binderName; SourceKind = sourceKind; IDisposable disable; if (sourceKind == SourceKindEnum.AbsRoot) { // TODO: Subscribe to RootNodeChanged instead. disable = notifyParentChangedSource.SubscribeToParentNodeHasChanged(ParentNodeHasChanged_Handler); ParentChangedSource = disable ?? throw new InvalidOperationException($"Could not subscribe to EventHandler<PSNodeParentChangedEventArgs> ParentNodeHasChanged for {PathElement}."); } else { disable = notifyParentChangedSource.SubscribeToParentNodeHasChanged(ParentNodeHasChanged_Handler); ParentChangedSource = disable ?? throw new InvalidOperationException($"Could not subscribe to EventHandler<PSNodeParentChangedEventArgs> ParentNodeHasChanged for {PathElement}."); } }
// ActionNoParams protected SubscriptionKeyGen(ExKeyT sourcePropId, Action action, SubscriptionPriorityGroup subscriptionPriorityGroup, bool keepRef, Func <ISubscriptionKeyGen, IProvideHandlerDispatchDelegateCaches, ISubscription> subscriptionFactory) { OwnerPropId = sourcePropId; PropertyType = null; SubscriptionKind = SubscriptionKind.ActionNoParams; SubscriptionPriorityGroup = subscriptionPriorityGroup; //SubscriptionTargetKind = GetKindOfTarget(action.Target, keepRef); //GenDoWhenChanged = null; //Action = action; object target = action.Target ?? throw new ArgumentNullException(nameof(action.Target)); Target_Wrk = new WeakRefKey(target); Method = action.Method ?? throw new ArgumentNullException(nameof(action.Method)); SubscriptionFactory = subscriptionFactory; BindingFactory = null; HasBeenUsed = false; }
public LocalBinder(PSAccessServiceInterface propStoreAccessService, ExKeyT ownerPropId, LocalBindingInfo bindingInfo) { _propStoreAccessService_wr = new WeakReference <PSAccessServiceInterface>(propStoreAccessService); _bindingTarget = ownerPropId; _bindingInfo = bindingInfo; _storeNodeUpdateReceiver = null; // Get the PropStore Node for the IPropBag object hosting the property that is the target of the binding. _ourNode = GetPropBagNode(propStoreAccessService); PropIdType propId = _bindingTarget.Level2Key; _targetObject = _ourNode.PropBagProxy; if (_targetObject.TryGetTarget(out IPropBagInternal propBag)) { _propertyName = GetPropertyName(propStoreAccessService, propBag, propId, out PropStorageStrategyEnum storageStrategy); _targetHasStore = storageStrategy; } _pathElements = GetPathElements(_bindingInfo, out _isPathAbsolute, out _firstNamedStepIndex); if (_isPathAbsolute) { _rootListener = CreateAndListen(_ourNode, "root", SourceKindEnum.AbsRoot); } else { _rootListener = null; } _pathListeners = new OSCollection <T>(); _isComplete = StartBinding(_targetObject, _pathElements, _pathListeners, _isPathAbsolute); }
// Action<object, object> protected SubscriptionKeyGen(ExKeyT sourcePropId, Action <object, object> genAction, SubscriptionPriorityGroup subscriptionPriorityGroup, bool keepRef, Func <ISubscriptionKeyGen, IProvideHandlerDispatchDelegateCaches, ISubscription> subscriptionFactory) { OwnerPropId = sourcePropId; PropertyType = null; SubscriptionKind = SubscriptionKind.ObjectAction; SubscriptionPriorityGroup = subscriptionPriorityGroup; //SubscriptionTargetKind = GetKindOfTarget(genAction.Target, keepRef); //GenDoWhenChanged = genAction ?? throw new ArgumentNullException(nameof(genAction)); //Action = null; object target = genAction.Target ?? throw new InvalidOperationException($"The value for Target on the GenAction action, cannot be null."); Target_Wrk = new WeakRefKey(target); Method = genAction.Method ?? throw new ArgumentNullException(nameof(genAction.Method)); SubscriptionFactory = subscriptionFactory; BindingFactory = null; HasBeenUsed = false; }
public PSNodeParentChangedEventArgs(ExKeyT propId, ExKeyT oldPropBagParent, ExKeyT newPropBagParent) { PropId = propId; // The node whose parent is being changed. OldPropBagParent = oldPropBagParent; // The old parent. NewPropBagParent = newPropBagParent; // The new parent. }
public bool Contains(ExKeyT compKey) { bool result = _children.Keys.Contains(compKey); return(result); }
public bool SetValueFast(ExKeyT compKey, PropItemSetKeyType propItemSetKey, object value) { bool result = _propStoreAccessServiceProvider.SetValueFast(compKey, propItemSetKey, value); return(result); }
public object GetValueFast(ExKeyT compKey, PropItemSetKeyType propItemSetKey) { object result = _propStoreAccessServiceProvider.GetValueFast(compKey, propItemSetKey); return(result); }