コード例 #1
0
 public static void SynchronizeProxiedForLifetime(this IObservableObject obj, ConsoleApp app, string propertyName, Action handler, ILifetimeManager manager)
 {
     obj.SynchronizeForLifetime(propertyName, () =>
     {
         app.QueueAction(handler);
     }, manager);
 }
コード例 #2
0
        private void Watch(IObservableObject obj, string path = "root")
        {
            foreach (var existingTrackedProperty in trackedObservables.Where(o => o.Path.StartsWith(path)).ToList())
            {
                trackedObservables.Remove(existingTrackedProperty);
            }

            var trackedObservable = new TrackedObservable()
            {
                PropertyValue = obj, Path = path
            };

            trackedObservables.Add(trackedObservable);
            var trackingLifetime = trackedObservables.GetMembershipLifetime(trackedObservable);

            foreach (var property in obj.GetType().GetProperties())
            {
                if (obj is IObservableCollection && property.Name == "Item")
                {
                    continue;
                }
                bool isSyncing = true;
                obj.SynchronizeForLifetime(property.Name, () =>
                {
                    var myProp = property;
                    var val    = myProp.GetValue(obj);
                    if (val is IObservableObject)
                    {
                        Watch(val as IObservableObject, path + "." + myProp.Name);
                    }

                    if (isSyncing)
                    {
                        isSyncing = false;
                    }
                    else
                    {
                        if (undoRedoPending == false)
                        {
                            undoRedoStack.Do(new PropertyAssignmentAction(obj, myProp, obj.GetPrevious(myProp.Name)));
                        }
                        Changed.Fire();
                    }
                }, trackingLifetime);
            }

            if (obj is IObservableCollection)
            {
                var collection = obj as IObservableCollection;
                collection
                .WhereAs <IObservableObject>()
                .ForEach(child => Watch(child as IObservableObject, path + "[" + Guid.NewGuid() + "]"));

                collection.Added.SubscribeForLifetime((o) =>
                {
                    if (undoRedoPending == false)
                    {
                        undoRedoStack.Do(new AddToCollectionAction(collection, o, collection.LastModifiedIndex));
                    }

                    if (o is IObservableObject)
                    {
                        Watch(o as IObservableObject, path + "[" + Guid.NewGuid() + "]");
                    }
                    Changed.Fire();
                }, trackingLifetime);

                collection.Removed.SubscribeForLifetime((o) =>
                {
                    if (undoRedoPending == false)
                    {
                        undoRedoStack.Do(new RemovedFromCollectionAction(collection, o, collection.LastModifiedIndex));
                    }
                    if (o is IObservableObject)
                    {
                        var tracked = trackedObservables.Where(to => to.PropertyValue == o).Single();
                        foreach (var related in trackedObservables.Where(t => t.Path.StartsWith(tracked.Path)).ToList())
                        {
                            trackedObservables.Remove(related);
                        }
                    }
                    Changed.Fire();
                }, trackingLifetime);

                collection.AssignedToIndex.SubscribeForLifetime((args) => throw new NotSupportedException("Index assignments are not supported by observable documents"), trackingLifetime);
            }
        }