Skip to content

Commit da56a50

Browse files
author
Paul Betts
committed
Merge pull request #690 from reactiveui/really-fix-leak
Fix bug with deactivation.
2 parents 3039b8c + beaf5fc commit da56a50

File tree

3 files changed

+134
-1
lines changed

3 files changed

+134
-1
lines changed

ReactiveUI.Tests/ReactiveUI.Tests_Net45.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
<Compile Include="Winforms\ReactiveBindingListTests.cs" />
115115
<Compile Include="Winforms\RoutedViewHostTests.cs" />
116116
<Compile Include="Winforms\ViewModelViewHostTests.cs" />
117+
<Compile Include="Xaml\ActivationForViewFetcherTest.cs" />
117118
<Compile Include="Xaml\DependencyObjectObservableForPropertyTest.cs" />
118119
<Compile Include="ErrorsTest.cs" />
119120
<Compile Include="MessageBusTest.cs" />
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using System.Windows;
7+
using System.Windows.Controls;
8+
using Xunit;
9+
10+
namespace ReactiveUI.Tests
11+
{
12+
public class ActivationForViewFetcherTest
13+
{
14+
public class TestUserControl : UserControl, IActivatable
15+
{
16+
public TestUserControl()
17+
{
18+
19+
}
20+
}
21+
22+
[Fact]
23+
public void FrameworkElementIsActivatedAndDeactivated()
24+
{
25+
var uc = new TestUserControl();
26+
var activation = new ActivationForViewFetcher();
27+
28+
var obs = activation.GetActivationForView(uc);
29+
var activated = obs.CreateCollection();
30+
31+
RoutedEventArgs loaded = new RoutedEventArgs();
32+
loaded.RoutedEvent = FrameworkElement.LoadedEvent;
33+
34+
uc.RaiseEvent(loaded);
35+
36+
new[] { true }.AssertAreEqual(activated);
37+
38+
RoutedEventArgs unloaded = new RoutedEventArgs();
39+
unloaded.RoutedEvent = FrameworkElement.UnloadedEvent;
40+
41+
uc.RaiseEvent(unloaded);
42+
43+
new[] { true, false }.AssertAreEqual(activated);
44+
}
45+
46+
[Fact]
47+
public void IsHitTestVisibleActivatesFrameworkElement()
48+
{
49+
var uc = new TestUserControl();
50+
uc.IsHitTestVisible = false;
51+
var activation = new ActivationForViewFetcher();
52+
53+
var obs = activation.GetActivationForView(uc);
54+
var activated = obs.CreateCollection();
55+
56+
RoutedEventArgs loaded = new RoutedEventArgs();
57+
loaded.RoutedEvent = FrameworkElement.LoadedEvent;
58+
59+
uc.RaiseEvent(loaded);
60+
61+
// IsHitTestVisible still false
62+
new bool[0].AssertAreEqual(activated);
63+
64+
uc.IsHitTestVisible = true;
65+
66+
// IsHitTestVisible true
67+
new[] { true }.AssertAreEqual(activated);
68+
69+
RoutedEventArgs unloaded = new RoutedEventArgs();
70+
unloaded.RoutedEvent = FrameworkElement.UnloadedEvent;
71+
72+
uc.RaiseEvent(unloaded);
73+
74+
new[] { true, false }.AssertAreEqual(activated);
75+
}
76+
77+
[Fact]
78+
public void IsHitTestVisibleDeactivatesFrameworkElement()
79+
{
80+
var uc = new TestUserControl();
81+
var activation = new ActivationForViewFetcher();
82+
83+
var obs = activation.GetActivationForView(uc);
84+
var activated = obs.CreateCollection();
85+
86+
RoutedEventArgs loaded = new RoutedEventArgs();
87+
loaded.RoutedEvent = FrameworkElement.LoadedEvent;
88+
89+
uc.RaiseEvent(loaded);
90+
91+
new[] { true }.AssertAreEqual(activated);
92+
93+
uc.IsHitTestVisible = false;
94+
95+
new[] { true, false }.AssertAreEqual(activated);
96+
}
97+
98+
[Fact]
99+
public void FrameworkElementIsActivatedAndDeactivatedWithHitTest()
100+
{
101+
var uc = new TestUserControl();
102+
var activation = new ActivationForViewFetcher();
103+
104+
var obs = activation.GetActivationForView(uc);
105+
var activated = obs.CreateCollection();
106+
107+
RoutedEventArgs loaded = new RoutedEventArgs();
108+
loaded.RoutedEvent = FrameworkElement.LoadedEvent;
109+
110+
uc.RaiseEvent(loaded);
111+
112+
new[] { true }.AssertAreEqual(activated);
113+
114+
// this should deactivate it
115+
uc.IsHitTestVisible = false;
116+
117+
new[] { true, false }.AssertAreEqual(activated);
118+
119+
// this should activate it
120+
uc.IsHitTestVisible = true;
121+
122+
new[] { true, false, true }.AssertAreEqual(activated);
123+
124+
RoutedEventArgs unloaded = new RoutedEventArgs();
125+
unloaded.RoutedEvent = FrameworkElement.UnloadedEvent;
126+
127+
uc.RaiseEvent(unloaded);
128+
129+
new[] { true, false, true, false }.AssertAreEqual(activated);
130+
}
131+
}
132+
}

ReactiveUI/Xaml/ActivationForViewFetcher.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public IObservable<bool> GetActivationForView(IActivatable view)
3636

3737
return viewLoaded
3838
.Merge(viewUnloaded)
39-
.Select(b => b ? fe.WhenAnyValue(x => x.IsHitTestVisible).Where(hv => hv && b) : Observable.Empty<bool>())
39+
.Select(b => b ? fe.WhenAnyValue(x => x.IsHitTestVisible).Select(hv => hv && b).SkipWhile(x => !x) : Observable.Return(b))
4040
.Switch()
4141
.DistinctUntilChanged();
4242
}

0 commit comments

Comments
 (0)