コード例 #1
0
        /// <summary>
        ///     Watches the specified source.
        /// </summary>
        /// <param name="source">
        ///     The source.
        /// </param>
        /// <param name="property">
        ///     The property.
        /// </param>
        /// <returns>
        ///     The <see cref="WeakCommandBinding"/>.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">
        ///     The source can not be null.
        /// </exception>
        public WeakCommandBinding Watch(object source, string property)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            var bindContext = new BindContext(source, property);

            var       entry = new WeakEntry(null, bindContext.Source, property);
            WeakEvent watchEvent;

            if (this.watchEvents.ContainsKey(entry))
            {
                watchEvent = this.watchEvents[entry];
            }
            else
            {
                watchEvent = new WeakEvent(this);
                this.watchEvents.Add(entry, watchEvent);
            }

            string propertyName = property.Contains(".") ? property.Right(".") : property;

            watchEvent.AttachEvent(
                bindContext,
                WeakPropertyBinding.PropertyChangedEventName,
                WatchEventCallbackMethod,
                (o, args) => string.Equals(((PropertyChangedEventArgs)args).PropertyName, propertyName));

            this.RaiseCanExecuteChanged();

            return(this);
        }
コード例 #2
0
        public void Test_WeakBindEvent_NormalProperty()
        {
            var viewModel = new TestViewModel();
            var view = new TestView();
            var propertyBinding = new WeakPropertyBinding(view, "Text1", viewModel, "Name")
                .Initialize<WeakPropertyBinding>();

            var weakEvent = new WeakEvent(viewModel);

            Assert.IsFalse(weakEvent.IsAttached);
        }
コード例 #3
0
            /// <summary>
            ///     Detaches the source.
            /// </summary>
            /// <param name="source">
            ///     The source.
            /// </param>
            protected override void DetachSource(object source)
            {
                base.DetachSource(source);

                if (source != null && source.GetType().ContainsEvent(WeakCollectionBinding.CollectionChangedEventName))
                {
                    if (collectionWeakEvent != null)
                    {
                        collectionWeakEvent.DetachEvent();
                        collectionWeakEvent = null;
                    }
                }
            }
コード例 #4
0
            /// <summary>
            ///     Attaches the source.
            /// </summary>
            /// <param name="source">
            ///     The source.
            /// </param>
            protected override void AttachSource(object source)
            {
                base.AttachSource(source);

                if (source != null && source.GetType().ContainsEvent(WeakCollectionBinding.CollectionChangedEventName))
                {
                    if (collectionWeakEvent != null)
                    {
                        collectionWeakEvent.DetachEvent();
                    }

                    if (collectionWeakEvent == null)
                    {
                        collectionWeakEvent = new WeakEvent(this);
                    }

                    collectionWeakEvent.AttachEvent(source, null, WeakCollectionBinding.CollectionChangedEventName, "OnSourceCollectionChanged");
                }
            }
コード例 #5
0
        /// <summary>
        ///     UnWatch the source property.
        /// </summary>
        /// <param name="source">
        ///     The source.
        /// </param>
        /// <param name="property">
        ///     The property.
        /// </param>
        /// <returns>
        ///     The <see cref="WeakCommandBinding"/>.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">
        ///     The source can not be null.
        /// </exception>
        public WeakCommandBinding UnWatch(object source, string property)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            var bindSource = new BindContext(source, property);

            var entry = new WeakEntry(null, bindSource.Source, property);

            if (this.watchEvents.ContainsKey(entry))
            {
                WeakEvent watchEvent = this.watchEvents[entry];
                watchEvent.DetachEvent();
                this.watchEvents.Remove(entry);
            }

            this.RaiseCanExecuteChanged();

            return(this);
        }
コード例 #6
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="WeakCommandBinding"/> class.
 /// </summary>
 /// <param name="target">
 ///     The target.
 /// </param>
 /// <param name="targetProperty">
 ///     The target property.
 /// </param>
 /// <param name="source">
 ///     The source.
 /// </param>
 /// <param name="sourceProperty">
 ///     The source property.
 /// </param>
 public WeakCommandBinding(object target, string targetProperty, object source, string sourceProperty)
     : base(target, targetProperty, source, sourceProperty)
 {
     this.commandCanExecuteEvent = new WeakEvent(this);
 }
コード例 #7
0
            /// <summary>
            ///     Detaches the source.
            /// </summary>
            /// <param name="source">
            ///     The source.
            /// </param>
            protected override void DetachSource(object source)
            {
                base.DetachSource(source);

                if (source != null && source.GetType().ContainsEvent(WeakCollectionBinding.CollectionChangedEventName))
                {
                    if (collectionWeakEvent != null)
                    {
                        collectionWeakEvent.DetachEvent();
                        collectionWeakEvent = null;
                    }
                }
            }
コード例 #8
0
            /// <summary>
            ///     Attaches the source.
            /// </summary>
            /// <param name="source">
            ///     The source.
            /// </param>
            protected override void AttachSource(object source)
            {
                base.AttachSource(source);

                if (source != null && source.GetType().ContainsEvent(WeakCollectionBinding.CollectionChangedEventName))
                {
                    if (collectionWeakEvent != null)
                    {
                        collectionWeakEvent.DetachEvent();
                    }

                    if (collectionWeakEvent == null)
                    {
                        collectionWeakEvent = new WeakEvent(this);
                    }

                    collectionWeakEvent.AttachEvent(source, null, WeakCollectionBinding.CollectionChangedEventName, "OnSourceCollectionChanged");
                }
            }
コード例 #9
0
        public void Test_MemoryLeak_WeakEvent()
        {
            // 1. Normal Event will hold the strong reference which prevent the GC collect.
            var view = new TestView();
            var viewModel = new TestViewModel();
            var reference = new WeakReference(view);

            viewModel.TestViewModelEvent += view.OnEventOccured;
            viewModel.RaiseTestViewModelEvent();
            Assert.AreEqual(1, view.EventCount);
            Assert.AreEqual(1, viewModel.GetTestViewModelEventInvocationCount());

            view = null;
            GC.Collect();
            Assert.IsTrue(reference.IsAlive); // Still live

            viewModel.TestViewModelEvent -= reference.GetTarget<TestView>().OnEventOccured;
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            Assert.IsFalse(reference.IsAlive);

            reference = null;
            Assert.IsNull(reference.GetTarget<TestView>());

            // 2. WeakEvent hold the weak reference which will not prevent GC collect.
            var view2 = new TestView();
            var viewModel2 = new TestViewModel();
            var reference2 = new WeakReference(view2);

            var weakEvent = new WeakEvent(view2);
            weakEvent.AttachEvent(viewModel2, null, "TestViewModelEvent", "OnEventOccured");
            viewModel2.RaiseTestViewModelEvent();

            Assert.AreEqual(1, view2.EventCount);

            view2 = null;
            GC.Collect();
            Assert.IsFalse(reference2.IsAlive);

            viewModel2.RaiseTestViewModelEvent();
            Assert.AreEqual(0, viewModel2.GetTestViewModelEventInvocationCount());
        }