Skip to content

Commit 42e580f

Browse files
committed
Fixed some stuff, added an ICreatesObservableForProperty for WinForms
1 parent d968d35 commit 42e580f

File tree

8 files changed

+162
-256
lines changed

8 files changed

+162
-256
lines changed

ReactiveUI.Platforms/PlatformUnitTestDetector.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
using Windows.ApplicationModel;
1111
#endif
1212

13+
#if WINFORMS
14+
namespace ReactiveUI.Winforms
15+
#else
1316
namespace ReactiveUI
17+
#endif
1418
{
1519
/// <summary>
1620
/// Because RxUI.dll is in a PLib, it doesn't have the SuperPowers it needs

ReactiveUI.Platforms/ReactiveUI.Winforms_Net45.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<DebugType>full</DebugType>
3232
<Optimize>false</Optimize>
3333
<OutputPath>bin\Debug\Net45\</OutputPath>
34-
<DefineConstants>DEBUG;TRACE;NET_45</DefineConstants>
34+
<DefineConstants>TRACE;DEBUG;WINFORMS</DefineConstants>
3535
<ErrorReport>prompt</ErrorReport>
3636
<WarningLevel>4</WarningLevel>
3737
<CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
@@ -65,7 +65,7 @@
6565
<DebugType>pdbonly</DebugType>
6666
<Optimize>true</Optimize>
6767
<OutputPath>bin\Release\Net45\</OutputPath>
68-
<DefineConstants>TRACE;NET_45</DefineConstants>
68+
<DefineConstants>TRACE;WINFORMS</DefineConstants>
6969
<ErrorReport>prompt</ErrorReport>
7070
<WarningLevel>4</WarningLevel>
7171
<CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
@@ -123,12 +123,13 @@
123123
</ItemGroup>
124124
<ItemGroup>
125125
<Compile Include="ComponentModelTypeConverter.cs" />
126+
<Compile Include="PlatformUnitTestDetector.cs" />
126127
<Compile Include="Winforms\ReactiveBindingList.cs" />
127128
<Compile Include="Winforms\CreatesCommandBinding.cs" />
128129
<Compile Include="Winforms\PlatformOperations.cs" />
129-
<Compile Include="Winforms\PlatformUnitTestDetector.cs" />
130130
<Compile Include="Winforms\Properties\AssemblyInfo.cs" />
131131
<Compile Include="Winforms\Registrations.cs" />
132+
<Compile Include="Winforms\WinformsCreatesObservableForProperty.cs" />
132133
<Compile Include="Winforms\WinformsDefaultPropertyBinding.cs" />
133134
</ItemGroup>
134135
<ItemGroup>

ReactiveUI.Platforms/Winforms/PlatformUnitTestDetector.cs

Lines changed: 0 additions & 99 deletions
This file was deleted.

ReactiveUI.Platforms/Winforms/Registrations.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@
77
using System.Windows;
88
using ReactiveUI;
99
using System.Reactive.Concurrency;
10-
10+
using System.Windows.Forms;
1111

1212
namespace ReactiveUI.Winforms
1313
{
14-
using System.Windows.Forms;
15-
1614
/// <summary>
1715
/// Ignore me. This class is a secret handshake between RxUI and RxUI.Xaml
1816
/// in order to register certain classes on startup that would be difficult
@@ -28,7 +26,7 @@ public void Register(Action<Func<object>, Type> registerFunction)
2826

2927
registerFunction(() => new WinformsDefaultPropertyBinding(), typeof(IDefaultPropertyBindingProvider));
3028
registerFunction(() => new CreatesWinformsCommandBinding(), typeof(ICreatesCommandBinding));
31-
29+
registerFunction(() => new WinformsCreatesObservableForProperty(), typeof(ICreatesObservableForProperty));
3230

3331
RxApp.InUnitTestRunnerOverride = PlatformUnitTestDetector.InUnitTestRunner();
3432
if (RxApp.InUnitTestRunner()) {
@@ -37,7 +35,6 @@ public void Register(Action<Func<object>, Type> registerFunction)
3735

3836
WindowsFormsSynchronizationContext.AutoInstall = true;
3937
RxApp.MainThreadScheduler = new WaitForDispatcherScheduler(() => new SynchronizationContextScheduler(new WindowsFormsSynchronizationContext()));
40-
4138
}
4239
}
4340
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reactive.Disposables;
5+
using System.Reactive.Linq;
6+
using System.Reflection;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
10+
namespace ReactiveUI.Winforms
11+
{
12+
public class WinformsCreatesObservableForProperty : ICreatesObservableForProperty
13+
{
14+
static readonly MemoizingMRUCache<Tuple<Type, string>, EventInfo> eventInfoCache = new MemoizingMRUCache<Tuple<Type, string>, EventInfo>((pair, _) => {
15+
return pair.Item1.GetEvents(System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)
16+
.FirstOrDefault(x => x.Name == pair.Item2 + "Changed");
17+
}, RxApp.SmallCacheLimit);
18+
19+
public int GetAffinityForObject(Type type, string propertyName, bool beforeChanged = false)
20+
{
21+
if (!type.FullName.ToLowerInvariant().StartsWith("system.windows.forms")) return 0;
22+
23+
lock (eventInfoCache) {
24+
var ei = eventInfoCache.Get(Tuple.Create(type, propertyName));
25+
return (beforeChanged == false && ei != null) ? 8 : 0;
26+
}
27+
}
28+
29+
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, string propertyName, bool beforeChanged = false)
30+
{
31+
var type = sender.GetType();
32+
var ei = default(EventInfo);
33+
var getter = Reflection.GetValueFetcherOrThrow(type, propertyName);
34+
35+
lock (eventInfoCache) {
36+
ei = eventInfoCache.Get(Tuple.Create(type, propertyName));
37+
}
38+
39+
return Observable.Create<IObservedChange<object, object>>(subj => {
40+
bool completed = false;
41+
var handler = new EventHandler((o, e) => {
42+
if (completed) return;
43+
try {
44+
subj.OnNext(new ObservedChange<object, object>() { Sender = sender, PropertyName = propertyName, Value = getter(sender) });
45+
} catch (Exception ex) {
46+
subj.OnError(ex);
47+
completed = true;
48+
}
49+
});
50+
51+
ei.AddEventHandler(sender, handler);
52+
return Disposable.Create(() => ei.RemoveEventHandler(sender, handler));
53+
});
54+
}
55+
}
56+
}

ReactiveUI.Tests/ReactiveUI.Tests_Net45.csproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@
114114
<Compile Include="Winforms\CommandBindingTests.cs">
115115
<SubType>Component</SubType>
116116
</Compile>
117-
<Compile Include="Winforms\DefaultPropertyBindingTests.cs" />
117+
<Compile Include="Winforms\DefaultPropertyBindingTests.cs">
118+
<SubType>Component</SubType>
119+
</Compile>
118120
<Compile Include="Winforms\ReactiveBindingListTests.cs" />
119121
<Compile Include="Xaml\DependencyObjectObservableForPropertyTest.cs" />
120122
<Compile Include="ErrorsTest.cs" />
@@ -147,7 +149,7 @@
147149
<Name>ReactiveUI.NLog_Net45</Name>
148150
</ProjectReference>
149151
<ProjectReference Include="..\ReactiveUI.Platforms\ReactiveUI.Winforms_Net45.csproj">
150-
<Project>{F5ECBDE5-E525-4482-B568-63217BCB0A0B}</Project>
152+
<Project>{f5ecbde5-e525-4482-b568-63217bcb0a0b}</Project>
151153
<Name>ReactiveUI.Winforms_Net45</Name>
152154
</ProjectReference>
153155
<ProjectReference Include="..\ReactiveUI.Testing\ReactiveUI.Testing_Net45.csproj">

0 commit comments

Comments
 (0)