// 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 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 PropDoWhenChangedField(object target, MethodInfo method, SubscriptionKind subscriptionKind, SubscriptionPriorityGroup priorityGroup, bool methodIsLocal, Type declaringType, string fullClassName, string instanceKey) { Target = target; // ?? throw new ArgumentNullException(nameof(target)); Method = method ?? throw new ArgumentNullException(nameof(method)); SubscriptionKind = subscriptionKind; PriorityGroup = priorityGroup; MethodIsLocal = methodIsLocal; DeclaringType = declaringType; // ?? throw new ArgumentNullException(nameof(declaringType)); FullClassName = fullClassName; // ?? throw new ArgumentNullException(nameof(fullClassName)); InstanceKey = instanceKey; // ?? throw new ArgumentNullException(nameof(instanceKey)); MethodName = method.Name; }
// 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; }
// Keep items of the same target group together and // makes sure that all items in a lower numbered target group come before items in a higher numbered group. // Adds new items at the 'end' of it's target group. private ISubscription AddSubscription(ISubscription s) { SubscriptionPriorityGroup spg = s.SubscriptionPriorityGroup; if (_subs.Count == 0 || spg == SubscriptionPriorityGroup.Logging) { _subs.Add(s); return(s); } int ptr = _subs.Count - 1; while (ptr > -1 && _subs[ptr].SubscriptionPriorityGroup > spg) { ptr--; } if (ptr == -1) { // No existing items in the target group and all existing items are part of a group that comes 'later' than the target group. // insert before the first item. _subs.Insert(0, s); } else if (ptr == _subs.Count - 1) { // Very last sub in existing list is part of the target group, insert at end. _subs.Add(s); //_subs.Insert(_subs.Count - 1, s); } else { // Insert just after found item. _subs.Insert(ptr + 1, s); } return(s); }
// 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; }
// 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; }
private IPropItemModel ProcessProp(IPropTemplateItem pi, DoWhenChangedHelper doWhenChangedHelper) { PropStorageStrategyEnum storageStrategy = pi.StorageStrategy; bool typeIsSolid = pi.TypeIsSolid; string extraInfo = pi.ExtraInfo; IPropItemModel rpi = new PropItemModel ( type: pi.PropertyType, name: pi.PropertyName, storageStrategy: storageStrategy, typeIsSolid: typeIsSolid, propKind: pi.PropKind, propTypeInfoField: null, initialValueField: null, extraInfo: extraInfo, comparer: null, itemType: null, binderField: null, mapperRequest: null, propCreator: null ); bool isCProp = pi.PropKind.IsCollection(); bool foundTypeInfoField = false; ItemCollection items = ((PropItem)pi).Items; foreach (Control uc in items) { // ToDo: Find and process this field first, and then enter the enclosing foreach loop. // because one day, some of the other processing may depend on the PropertyType. // Type Info Field if (uc is DRM.PropBagControlsWPF.TypeInfoField tif) { foundTypeInfoField = true; Type propertyType = GetTypeFromInfoField(tif, pi.PropKind, pi.PropertyType, out Type itemType); if (isCProp) { rpi.CollectionType = propertyType; rpi.ItemType = itemType; } else { rpi.PropertyType = propertyType; rpi.ItemType = null; } } // Initial Value Field else if (uc is InitialValueField ivf) { IPropInitialValueField rivf; // TODO: Add error handling here. if (ivf.PropBagFullClassName != null) { rivf = PropInitialValueField.FromPropBagFCN(ivf.PropBagFullClassName); } else if (ivf.CreateNew) { rivf = PropInitialValueField.UseCreateNew; } else { rivf = new PropInitialValueField(ivf.InitialValue, ivf.SetToDefault, ivf.SetToUndefined, ivf.SetToNull, ivf.SetToEmptyString); } rpi.InitialValueField = rivf; } // Do When Changed Field else if (uc is DRM.PropBagControlsWPF.PropDoWhenChangedField dwc) { MethodInfo mi = doWhenChangedHelper.GetMethodAndSubKind(dwc, rpi.PropertyType, rpi.PropertyName, out SubscriptionKind subscriptionKind); SubscriptionPriorityGroup priorityGroup = dwc?.DoAfterNotify ?? false ? SubscriptionPriorityGroup.Last : SubscriptionPriorityGroup.Standard; IPropDoWhenChangedField rdwc = new DRM.PropBag.PropDoWhenChangedField ( target: null, method: mi, subscriptionKind: subscriptionKind, priorityGroup: priorityGroup, methodIsLocal: true, declaringType: null, fullClassName: null, instanceKey: null ); rpi.DoWhenChangedField = rdwc; } // Comparer Field else if (uc is DRM.PropBagControlsWPF.PropComparerField pcf) { IPropComparerField rpcf = new PropBag.PropComparerField(pcf.ComparerFunc.Comparer, pcf.UseRefEquality); rpi.ComparerField = rpcf; } // Local Binder Field else if (uc is DRM.PropBagControlsWPF.PropBinderField binderField) { IPropBinderField rBinderField = new PropBag.PropBinderField(binderField.Path); rpi.BinderField = rBinderField; rpi.MapperRequestResourceKey = binderField.MapperRequestResourceKey; } } if (!foundTypeInfoField) { if (isCProp) { Type propertyType = GetTypeFromInfoField(null, pi.PropKind, pi.PropertyType, out Type itemType); rpi.CollectionType = propertyType; rpi.ItemType = itemType; } else if (pi.PropKind == PropKindEnum.CollectionView) { rpi.PropertyType = typeof(ListCollectionView); rpi.CollectionType = rpi.PropertyType; rpi.ItemType = pi.PropertyType; } else { // TODO: Check other PropKinds. // Do Nothing. } } return(rpi); }