예제 #1
0
        private static void ConditionallyRegisterDependentInstance(INotifyPropertyChanged target)
        {
            if (instanceTable.TryGetValue(target, out _))
            {
                return;
            }

            lock (target)
            {
                if (instanceTable.TryGetValue(target, out _))
                {
                    return;
                }
                instanceTable.Add(target, null);
            }

            Type dependentType = target.GetType();

            if (!dependencyDefinitions.TryGetValue(dependentType, out var dependenciesByPropertyName))
            {
                return;
            }

            foreach (var dependency in dependenciesByPropertyName)
            {
                string targetPropertyName = dependency.Key;

                foreach (JsonPath jsonpath in dependency.Value)
                {
                    var dependencyNodes           = ImmutableQueue.Create(jsonpath.Root.Nodes.ToArray());
                    INotifyPropertyChanged source = target;
                    source.ForwardPropertyChanged(dependencyNodes, target, targetPropertyName);
                }
            }
        }
예제 #2
0
        private static Action ForwardPropertyChanged(this INotifyPropertyChanged source, ImmutableQueue <JsonPathNode> dependencyNodes, INotifyPropertyChanged target, string targetPropertyName)
        {
            WeakReference <INotifyPropertyChanged> wr = new WeakReference <INotifyPropertyChanged>(target);
            Action unsubscribe = null;

            dependencyNodes = dependencyNodes.Dequeue(out var node);

            switch (node)
            {
            case JsonPathPropertySelectorNode propertySelectorNode:
                string sourcePropertyName = propertySelectorNode.PropertyName;
                unsubscribe = source.ForwardPropertyChanged(sourcePropertyName, target, targetPropertyName);

                if (dependencyNodes.IsEmpty)
                {
                    return(unsubscribe);
                }

                Action unsubscribeNested = null;

                if (propertySelectorNode.GetValue(source) is INotifyPropertyChanged nestedSource)
                {
                    unsubscribeNested = nestedSource.ForwardPropertyChanged(dependencyNodes, target, targetPropertyName);
                    unsubscribe      += unsubscribeNested;
                }

                unsubscribe += source.Bind <INotifyPropertyChanged, object>(sourcePropertyName, (value) =>
                {
                    unsubscribe -= unsubscribeNested;
                    unsubscribeNested?.Invoke();
                    if (!wr.TryGetTarget(out var t))
                    {
                        return;
                    }

                    if (value is INotifyPropertyChanged nestedSrc)
                    {
                        unsubscribeNested = nestedSrc.ForwardPropertyChanged(dependencyNodes, t, targetPropertyName);
                        unsubscribe      += unsubscribeNested;
                    }
                });