Skip to content

Commit 6316f79

Browse files
Merge branch 'bugfix/v1.3.2' into develop
2 parents 5b84794 + cecc3fc commit 6316f79

File tree

7 files changed

+188
-11
lines changed

7 files changed

+188
-11
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<assembly name="Shuriken.Wpf, Version=1.3.2.0">
2+
<member name="M:Shuriken.AsyncCommand.#ctor(System.Func{System.Threading.Tasks.Task},System.Func{System.Boolean},Shuriken.CommandOptions)">
3+
<parameter name="execute">
4+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
5+
</parameter>
6+
</member>
7+
<member name="M:Shuriken.AsyncCommand.#ctor(System.Func{System.Threading.CancellationToken,System.Threading.Tasks.Task},System.Func{System.Boolean},Shuriken.CommandOptions)">
8+
<parameter name="execute">
9+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
10+
</parameter>
11+
</member>
12+
<member name="M:Shuriken.AsyncCommand.#ctor(System.Func{Shuriken.CommandExecutionController,System.Threading.CancellationToken,System.Threading.Tasks.Task},System.Func{System.Boolean},Shuriken.CommandOptions)">
13+
<parameter name="execute">
14+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
15+
</parameter>
16+
</member>
17+
<member name="M:Shuriken.AsyncCommand`1.#ctor(System.Func{`0,System.Threading.Tasks.Task},System.Func{`0,System.Boolean},Shuriken.CommandOptions)">
18+
<parameter name="execute">
19+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
20+
</parameter>
21+
</member>
22+
<member name="M:Shuriken.AsyncCommand`1.#ctor(System.Func{`0,System.Threading.CancellationToken,System.Threading.Tasks.Task},System.Func{`0,System.Boolean},Shuriken.CommandOptions)">
23+
<parameter name="execute">
24+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
25+
</parameter>
26+
</member>
27+
<member name="M:Shuriken.AsyncCommand`1.#ctor(System.Func{`0,Shuriken.CommandExecutionController,System.Threading.CancellationToken,System.Threading.Tasks.Task},System.Func{`0,System.Boolean},Shuriken.CommandOptions)">
28+
<parameter name="execute">
29+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
30+
</parameter>
31+
</member>
32+
<member name="M:Shuriken.Command.#ctor(System.Action,System.Func{System.Boolean},Shuriken.CommandOptions)">
33+
<parameter name="execute">
34+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
35+
</parameter>
36+
</member>
37+
<member name="M:Shuriken.Command.#ctor(System.Action{System.Threading.CancellationToken},System.Func{System.Boolean},Shuriken.CommandOptions)">
38+
<parameter name="execute">
39+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
40+
</parameter>
41+
</member>
42+
<member name="M:Shuriken.Command.#ctor(System.Action{Shuriken.CommandExecutionController,System.Threading.CancellationToken},System.Func{System.Boolean},Shuriken.CommandOptions)">
43+
<parameter name="execute">
44+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
45+
</parameter>
46+
</member>
47+
<member name="M:Shuriken.Command`1.#ctor(System.Action{`0},System.Func{`0,System.Boolean},Shuriken.CommandOptions)">
48+
<parameter name="execute">
49+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
50+
</parameter>
51+
</member>
52+
<member name="M:Shuriken.Command`1.#ctor(System.Action{`0,System.Threading.CancellationToken},System.Func{`0,System.Boolean},Shuriken.CommandOptions)">
53+
<parameter name="execute">
54+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
55+
</parameter>
56+
</member>
57+
<member name="M:Shuriken.Command`1.#ctor(System.Action{`0,Shuriken.CommandExecutionController,System.Threading.CancellationToken},System.Func{`0,System.Boolean},Shuriken.CommandOptions)">
58+
<parameter name="execute">
59+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
60+
</parameter>
61+
</member>
62+
<member name="P:Shuriken.CommandBase.Options">
63+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
64+
</member>
65+
<member name="P:Shuriken.CommandExecutionController.Execution">
66+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
67+
</member>
68+
<member name="M:Shuriken.ParameterizedCommand`1.CanExecute(`0)">
69+
<attribute ctor="M:JetBrains.Annotations.PureAttribute.#ctor" />
70+
</member>
71+
<member name="M:Shuriken.ParameterlessCommand.CanExecute">
72+
<attribute ctor="M:JetBrains.Annotations.PureAttribute.#ctor" />
73+
</member>
74+
<member name="P:Shuriken.RunningCommandExecution.CancelCommand">
75+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
76+
</member>
77+
<member name="M:Shuriken.Diagnostics.EventListener.ToDebugMessage(System.Diagnostics.Tracing.EventWrittenEventArgs)">
78+
<attribute ctor="M:JetBrains.Annotations.PureAttribute.#ctor" />
79+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
80+
</member>
81+
<member name="M:Shuriken.Monitoring.ApplicationMonitorScope.#ctor(Shuriken.Monitoring.INotificationContext)">
82+
<parameter name="notificationContext">
83+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
84+
</parameter>
85+
</member>
86+
<member name="P:Shuriken.Monitoring.ApplicationMonitorScope.NotificationContext">
87+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
88+
</member>
89+
<member name="M:Shuriken.Monitoring.ApplicationMonitorScope.Suspend">
90+
<attribute ctor="M:JetBrains.Annotations.MustUseReturnValueAttribute.#ctor" />
91+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
92+
</member>
93+
<member name="M:Shuriken.Monitoring.INotificationContext.Invoke(System.Action)">
94+
<parameter name="action">
95+
<attribute ctor="M:JetBrains.Annotations.InstantHandleAttribute.#ctor" />
96+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
97+
</parameter>
98+
</member>
99+
<member name="M:Shuriken.Monitoring.INotificationContext.InvokeAsync(System.Action)">
100+
<attribute ctor="M:JetBrains.Annotations.PureAttribute.#ctor" />
101+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
102+
<parameter name="action">
103+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
104+
</parameter>
105+
</member>
106+
<member name="M:Shuriken.Monitoring.WpfNotificationContext.#ctor(System.Windows.Threading.Dispatcher)">
107+
<parameter name="dispatcher">
108+
<attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
109+
</parameter>
110+
</member>
111+
</assembly>

Sources/Shuriken.Deployment/Shuriken.Annotations.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package>
33
<metadata>
44
<id>Shuriken.Annotations</id>
5-
<version>1.3.1</version>
5+
<version>1.3.2</version>
66
<title>Shuriken Annotations</title>
77
<authors>Michael Damatov</authors>
88
<description>Annotations for the Shuriken library.</description>

Sources/Shuriken.Deployment/Shuriken.Deployment.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@
7777
</None>
7878
</ItemGroup>
7979
<ItemGroup>
80+
<Content Include="Annotations\Shuriken.Wpf\1.3.2.0.xml">
81+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
82+
</Content>
8083
<Content Include="Annotations\Shuriken.Wpf\1.3.1.0.xml">
8184
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
8285
</Content>

Sources/Shuriken.Wpf/Monitoring/_ValueBags/ParameterizedCommandValueBag.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,11 @@ public override void NotifyPropertyChanged(ObservableObject observableObject)
150150

151151
if (isIsExecutingChanged)
152152
{
153-
Debug.Assert(currentValue != null);
153+
var value = currentValue;
154154

155155
try
156156
{
157-
currentValue.NotifyCanExecuteChanged();
157+
value?.NotifyCanExecuteChanged();
158158
}
159159
catch (Exception e)
160160
{
@@ -167,9 +167,9 @@ public override void NotifyPropertyChanged(ObservableObject observableObject)
167167
{
168168
isIsExecutingChanged = false;
169169

170-
if (currentValue != null)
170+
if (value != null)
171171
{
172-
var isExecuting = GetCurrentIsExecuting(currentValue);
172+
var isExecuting = GetCurrentIsExecuting(value);
173173

174174
Debug.Assert(isIsExecutingValid);
175175
currentIsExecuting = isExecuting;

Sources/Shuriken.Wpf/Monitoring/_ValueBags/ParameterlessCommandValueBag.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,11 @@ public override void NotifyPropertyChanged(ObservableObject observableObject)
179179

180180
if (isCanExecuteChanged)
181181
{
182-
Debug.Assert(currentValue != null);
182+
var value = currentValue;
183183

184184
try
185185
{
186-
currentValue.NotifyCanExecuteChanged();
186+
value?.NotifyCanExecuteChanged();
187187
}
188188
catch (Exception e)
189189
{
@@ -196,7 +196,6 @@ public override void NotifyPropertyChanged(ObservableObject observableObject)
196196
{
197197
isCanExecuteChanged = false;
198198

199-
var value = currentValue;
200199
if (value != null)
201200
{
202201
var canExecute = GetCurrentGetExecute(value);

Sources/Shuriken.Wpf/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
// You can specify all the values or you can default the Build and Revision Numbers
3737
// by using the '*' as shown below:
3838
// [assembly: AssemblyVersion("1.0.*")]
39-
[assembly: AssemblyVersion("1.3.1.0")]
40-
[assembly: AssemblyFileVersion("1.3.1")]
39+
[assembly: AssemblyVersion("1.3.2.0")]
40+
[assembly: AssemblyFileVersion("1.3.2")]
4141

4242
[assembly: XmlnsDefinition("http://schemas.shuriken/view-models", @"Shuriken")]
4343
[assembly: XmlnsPrefix("http://schemas.shuriken/view-models", "sh")]

Sources/Tests.Shuriken.Wpf/ObservableObjectTests.cs

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.ComponentModel;
1+
using System;
2+
using System.ComponentModel;
23
using System.Diagnostics.CodeAnalysis;
34
using System.Threading.Tasks;
45
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -59,5 +60,68 @@ async void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
5960

6061
await Task.Delay(50).ConfigureAwait(false);
6162
});
63+
64+
sealed class MutableCommands : ObservableObject
65+
{
66+
[Observable]
67+
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")]
68+
public Command ParameterlessCommand { get; set; }
69+
70+
[Observable]
71+
public AsyncCommand<int> ParameterizedCommand { get; set; }
72+
}
73+
74+
[TestMethod]
75+
[DoNotParallelize]
76+
[SuppressMessage("ReSharper", "AccessToModifiedClosure")]
77+
public Task _MutableCommands() => ApplicationMonitorScopeController.ExecuteInApplicationMonitorScope(
78+
async monitorScope =>
79+
{
80+
// "Command" property becomes null after being assigned, so no further "can execute" change notification may be raised
81+
82+
var canExecute = false;
83+
84+
var parameterlessCommand = new Command(() => { }, () => canExecute);
85+
var parameterizedCommand = new AsyncCommand<int>(_ => Task.Delay(50));
86+
87+
var mutableCommands = new MutableCommands { ParameterlessCommand = parameterlessCommand, ParameterizedCommand = parameterizedCommand};
88+
89+
var parameterlessCommandEventRaiseCount = 0;
90+
var parameterizedCommandEventRaiseCount = 0;
91+
92+
void CommandOnCanExecuteChanged(object sender, EventArgs e) => parameterlessCommandEventRaiseCount++;
93+
void AsyncCommandOnCanExecuteChanged(object sender, EventArgs e) => parameterizedCommandEventRaiseCount++;
94+
95+
void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { }
96+
97+
mutableCommands.PropertyChanged += OnPropertyChanged;
98+
parameterlessCommand.CanExecuteChanged += CommandOnCanExecuteChanged;
99+
parameterizedCommand.CanExecuteChanged += AsyncCommandOnCanExecuteChanged;
100+
try
101+
{
102+
await Task.Delay(50).ConfigureAwait(false);
103+
104+
canExecute = true;
105+
await mutableCommands.ParameterizedCommand.Execute(0).ConfigureAwait(false);
106+
107+
await Task.Delay(100).ConfigureAwait(false);
108+
109+
mutableCommands.ParameterlessCommand = null;
110+
mutableCommands.ParameterizedCommand = null;
111+
112+
await Task.Delay(50).ConfigureAwait(false);
113+
}
114+
finally
115+
{
116+
parameterizedCommand.CanExecuteChanged -= AsyncCommandOnCanExecuteChanged;
117+
parameterlessCommand.CanExecuteChanged -= CommandOnCanExecuteChanged;
118+
mutableCommands.PropertyChanged -= OnPropertyChanged;
119+
}
120+
121+
Assert.AreEqual(1, parameterlessCommandEventRaiseCount);
122+
Assert.AreEqual(2, parameterizedCommandEventRaiseCount);
123+
124+
await Task.Delay(50).ConfigureAwait(false);
125+
});
62126
}
63127
}

0 commit comments

Comments
 (0)