diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj
index d9375e30ee..963726c158 100644
--- a/src/Avalonia.Base/Avalonia.Base.csproj
+++ b/src/Avalonia.Base/Avalonia.Base.csproj
@@ -117,6 +117,7 @@
+
diff --git a/src/Avalonia.Base/Utilities/WeakObservable.cs b/src/Avalonia.Base/Utilities/WeakObservable.cs
new file mode 100644
index 0000000000..c261cc0520
--- /dev/null
+++ b/src/Avalonia.Base/Utilities/WeakObservable.cs
@@ -0,0 +1,54 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System;
+using System.Reactive;
+using System.Reactive.Linq;
+
+namespace Avalonia.Utilities
+{
+ ///
+ /// Provides extension methods for working with weak event handlers.
+ ///
+ public static class WeakObservable
+ {
+ ///
+ /// Converts a .NET event conforming to the standard .NET event pattern into an observable
+ /// sequence, subscribing weakly.
+ ///
+ /// The type of the event args.
+ /// Object instance that exposes the event to convert.
+ /// Name of the event to convert.
+ ///
+ public static IObservable> FromEventPattern(
+ object target,
+ string eventName)
+ where TEventArgs : EventArgs
+ {
+ Contract.Requires(target != null);
+ Contract.Requires(eventName != null);
+
+ return Observable.Create>(observer =>
+ {
+ var handler = new Handler(observer);
+ WeakSubscriptionManager.Subscribe(target, eventName, handler);
+ return () => WeakSubscriptionManager.Unsubscribe(target, eventName, handler);
+ }).Publish().RefCount();
+ }
+
+ private class Handler : IWeakSubscriber where TEventArgs : EventArgs
+ {
+ private IObserver> _observer;
+
+ public Handler(IObserver> observer)
+ {
+ _observer = observer;
+ }
+
+ public void OnEvent(object sender, TEventArgs e)
+ {
+ _observer.OnNext(new EventPattern