Click here to Skip to main content
16,003,642 members
Home / Discussions / C#
   

C#

 
GeneralRe: Retrieve a date from the result of a query in a variable c # Pin
Sascha Lefèvre1-Feb-16 3:16
professionalSascha Lefèvre1-Feb-16 3:16 
QuestionReactive Extensions and WeakEvents Pin
Kenneth Haugland30-Jan-16 3:23
mvaKenneth Haugland30-Jan-16 3:23 
AnswerRe: Reactive Extensions and WeakEvents Pin
Sascha Lefèvre30-Jan-16 4:20
professionalSascha Lefèvre30-Jan-16 4:20 
GeneralRe: Reactive Extensions and WeakEvents Pin
Kenneth Haugland30-Jan-16 5:27
mvaKenneth Haugland30-Jan-16 5:27 
GeneralRe: Reactive Extensions and WeakEvents Pin
Sascha Lefèvre30-Jan-16 6:20
professionalSascha Lefèvre30-Jan-16 6:20 
GeneralRe: Reactive Extensions and WeakEvents Pin
Kenneth Haugland30-Jan-16 7:29
mvaKenneth Haugland30-Jan-16 7:29 
GeneralRe: Reactive Extensions and WeakEvents Pin
Sascha Lefèvre30-Jan-16 8:06
professionalSascha Lefèvre30-Jan-16 8:06 
AnswerRe: Reactive Extensions and WeakEvents Pin
Sascha Lefèvre30-Jan-16 11:42
professionalSascha Lefèvre30-Jan-16 11:42 
Kenneth Haugland wrote:
I also have sort of a side question, and that is how do I enable to write an Expression in the code that allows me to write:
ObservePropertyChanged(Myclass, s => s.MyPropertyInMyClass)
Caution: Code dump incoming! Smile | :)
C#
using System;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive;
using System.Reactive.Linq;
using System.Reflection;

namespace RxPropertyChanged
{
    class A : NotifierBase
    {
        public string ID { get; set; }

        public string Name
        {
            get { return name; }
            set { SetProperty(ref name, value); }
        }

        private string name;
    }

    class WeakPropertyChangedSubscriber<TTarget, TProperty>
        where TTarget : INotifyPropertyChanged
    {
        private Action<EventPattern<PropertyChangedEventArgs>> EventAction;

        public WeakPropertyChangedSubscriber(TTarget target, Expression<Func<TTarget, TProperty>> propertyExpr, Action<EventPattern<PropertyChangedEventArgs>> eventAction)
        {
            EventAction = eventAction;
            target.FromPropertyChanged(propertyExpr).SubscribeWeakly(this, HandleEvent);
        }

        private static void HandleEvent(WeakPropertyChangedSubscriber<TTarget, TProperty> subscriber, EventPattern<PropertyChangedEventArgs> item)
        {
            subscriber.EventAction(item);
        }
    }

    public static class IObservableExtensions
    {
        public static IObservable<EventPattern<PropertyChangedEventArgs>> FromPropertyChanged<TTarget, TProperty>(this TTarget target, Expression<Func<TTarget, TProperty>> propertyExpr)
            where TTarget : INotifyPropertyChanged
        {
            var propertyInfo = (propertyExpr.Body as MemberExpression)?.Member as PropertyInfo;

            if (propertyInfo == null)
                throw new ArgumentException("The specified expression does not reference a property.", nameof(propertyExpr));

            return Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                    eventHandler => (s, e) => eventHandler(s, e),
                    //            short for:
                    //eventHandler =>
                    //{
                    //    PropertyChangedEventHandler h = (s, e) => eventHandler(s, e);
                    //    return h;
                    //},
                    propertyChangedEventHandler => target.PropertyChanged += propertyChangedEventHandler,
                    propertyChangedEventHandler => target.PropertyChanged -= propertyChangedEventHandler)
                .Where(evt => evt.EventArgs.PropertyName == propertyInfo.Name);
        }

        public static IDisposable SubscribeWeakly<TEventPattern, TSubscriber>(this IObservable<TEventPattern> observable, TSubscriber subscriber, Action<TSubscriber, TEventPattern> onNext)
            where TSubscriber : class
        {
            if (onNext.Target != null)
                throw new ArgumentException("onNext must refer to a static method, or else the subscription will still hold a strong reference to target");

            var reference = new WeakReference(subscriber);

            IDisposable subscription = null;
            subscription = observable.Subscribe(item =>
            {
                var currentTarget = reference.Target as TSubscriber;
                if (currentTarget != null)
                {
                    onNext(currentTarget, item);
                }
                else
                {
                    Console.WriteLine("subscription.Dispose()");
                    subscription.Dispose();
                }
            });

            return subscription;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a1 = new A() { ID = "a1" };
            A a2 = new A() { ID = "a2" };

            Action<A, EventPattern<PropertyChangedEventArgs>> eventAction = (obj, evt) => Console.WriteLine($"{obj.ID}.{evt.EventArgs.PropertyName} = {obj.Name}");

            var subscriberA1 = new WeakPropertyChangedSubscriber<A, string>(a1, x => x.Name, evt => eventAction(a1, evt));
            var subscriberA2 = new WeakPropertyChangedSubscriber<A, string>(a2, x => x.Name, evt => eventAction(a2, evt));

            a1.Name = "name1.1";
            a2.Name = "name2.1";

            subscriberA1 = null;

            GC.Collect();
            Console.WriteLine("Full collection completed");

            a1.Name = "name1.2";
            a2.Name = "name2.2";

            Console.Read();
        }
    }
}
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson

GeneralRe: Reactive Extensions and WeakEvents Pin
Kenneth Haugland31-Jan-16 1:19
mvaKenneth Haugland31-Jan-16 1:19 
GeneralRe: Reactive Extensions and WeakEvents Pin
Sascha Lefèvre31-Jan-16 1:42
professionalSascha Lefèvre31-Jan-16 1:42 
GeneralRe: Reactive Extensions and WeakEvents Pin
Kenneth Haugland31-Jan-16 4:24
mvaKenneth Haugland31-Jan-16 4:24 
GeneralRe: Reactive Extensions and WeakEvents Pin
Sascha Lefèvre31-Jan-16 6:34
professionalSascha Lefèvre31-Jan-16 6:34 
GeneralRe: Reactive Extensions and WeakEvents Pin
Kenneth Haugland31-Jan-16 7:29
mvaKenneth Haugland31-Jan-16 7:29 
GeneralRe: Reactive Extensions and WeakEvents Pin
Kenneth Haugland31-Jan-16 11:27
mvaKenneth Haugland31-Jan-16 11:27 
QuestionTableLayoutPanel and .. surprise surprise .. weird behaviour 8) Pin
Emanuele Bonin30-Jan-16 1:24
Emanuele Bonin30-Jan-16 1:24 
Answer[SOLVED] TableLayoutPanel and .. surprise surprise .. weird behaviour 8) Pin
Emanuele Bonin30-Jan-16 2:17
Emanuele Bonin30-Jan-16 2:17 
GeneralRe: [SOLVED] TableLayoutPanel and .. surprise surprise .. weird behaviour 8) Pin
BillWoodruff30-Jan-16 2:46
professionalBillWoodruff30-Jan-16 2:46 
GeneralRe: [SOLVED] TableLayoutPanel and .. surprise surprise .. weird behaviour 8) Pin
Emanuele Bonin30-Jan-16 6:18
Emanuele Bonin30-Jan-16 6:18 
AnswerRe: TableLayoutPanel and .. surprise surprise .. weird behaviour 8) Pin
BillWoodruff30-Jan-16 2:39
professionalBillWoodruff30-Jan-16 2:39 
QuestionSubscribe to property changes using Reactive Extensions Pin
Kenneth Haugland29-Jan-16 2:18
mvaKenneth Haugland29-Jan-16 2:18 
AnswerRe: Subscribe to property changes using Reactive Extensions Pin
Pete O'Hanlon29-Jan-16 3:25
mvePete O'Hanlon29-Jan-16 3:25 
GeneralRe: Subscribe to property changes using Reactive Extensions Pin
Kenneth Haugland29-Jan-16 4:47
mvaKenneth Haugland29-Jan-16 4:47 
GeneralRe: Subscribe to property changes using Reactive Extensions Pin
Richard Deeming29-Jan-16 5:03
mveRichard Deeming29-Jan-16 5:03 
GeneralRe: Subscribe to property changes using Reactive Extensions Pin
Kenneth Haugland29-Jan-16 5:22
mvaKenneth Haugland29-Jan-16 5:22 
AnswerRe: Subscribe to property changes using Reactive Extensions Pin
Richard Deeming29-Jan-16 3:31
mveRichard Deeming29-Jan-16 3:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.