About Hasmukh patel

My Photo
Harrow, London, United Kingdom
Dot-Net developer with expertise in Web, WPF, Win-form applications. Have worked on Asp.net,mvc , WPF and Win-forms projects in c#.net language having Sql-Server/Oracle as database with service oriented architecture using test driven development. Having complete knowledge of SDLC and have successfully worked and implemented it on projects.

WPF Observble Extensions



using System;
using System.ComponentModel;
using System.Linq.Expressions;

namespace DemoCode.Shared.Extensions
{
    public static class ObservableExts
    {
        public static IObservable<IObservedChange<TSender, TValue>> ObservableForProperty<TSender, TValue>
            (this TSender This, Expression<Func<TSender, TValue>> property, bool beforeChange = false)
            where TSender : INotifyPropertyChanged
        {
            var observedChange = new ObservedChange<TSender, TValue>(This, property);
            return new Observable<TSender, TValue>(observedChange);
        }

        public static IDisposable Subscribe<TSource>(this IObservable<TSource> source, Action<TSource> onNext)
            where TSource : class
        {
            return new Unsubscriber<TSource>(source, onNext);
        }

    }

    internal interface INotifySender
    {
        INotifyPropertyChanged Sender { get; }
        string PropertyName { get; }
        TSource GetSource<TSource>();
    }

    public interface IObservedChange<out TSender, out TValue>
    {
        TSender Sender { get; }
        TValue Value { get; }
        string PropertyName { get; }
    }

    public class ObservedChange<TSender, TValue> : IObservedChange<TSender, TValue>
    {
        private Expression<Func<TSender, TValue>> _property;

        public ObservedChange(TSender sender, Expression<Func<TSender, TValue>> property)
        {
            Sender = sender;

            var expression = property.Body as MemberExpression;
            if (expression != null)
            {
                var member = expression.Member;
                PropertyName = member.Name;
            }
            _property = property;

        }

        public TSender Sender { get; private set; }
        public TValue Value { get { return (TValue)Sender.GetType().GetProperty(PropertyName).GetValue(Sender, null); } }
        public string PropertyName { get; private set; }
    }

    public class Observable<TSender, TValue> : IObservable<IObservedChange<TSender, TValue>>, INotifySender
    {
        public Observable(IObservedChange<TSender, TValue> observedChange)
        {
            ObservedChange = observedChange;
        }

        public IObservedChange<TSender, TValue> ObservedChange { get; private set; }

        public IDisposable Subscribe(IObserver<IObservedChange<TSender, TValue>> observer)
        {
            throw new NotImplementedException();
        }

        public INotifyPropertyChanged Sender
        {
            get { return ObservedChange.Sender as INotifyPropertyChanged; }
        }

        public string PropertyName
        {
            get { return ObservedChange.PropertyName; }
        }

        public TSource GetSource<TSource>()
        {
            return (TSource)ObservedChange;
        }
    }

    internal class Unsubscriber<TSource> : IDisposable
        where TSource : class
    {
        private IObservable<TSource> _source;
        private readonly Action<TSource> _onNext;
        private readonly INotifySender _notifySender;

        public Unsubscriber(IObservable<TSource> source, Action<TSource> onNext)
        {
            _source = source;
            _notifySender = source as INotifySender;
            if (_notifySender != null && _notifySender.Sender != null)
            {
                _notifySender.Sender.PropertyChanged += SenderPropertyChanged;
            }
            _onNext = onNext;
        }

        void SenderPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (_onNext != null && e.PropertyName == _notifySender.PropertyName)
            {
                //_onNext(_onNext.Target as TSource);
                System.Windows.Application.Current.Dispatcher
                    .Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                            (Action) (() => _onNext(_notifySender.GetSource<TSource>())));
            }
        }

        public void Dispose()
        {
            _notifySender.Sender.PropertyChanged -= SenderPropertyChanged;
        }
    }

}

No comments :